Merge changes I84b3ca1e,I41db99f8 into msm-3.0

* changes:
  ASoc: msm: Add support for adie RX & TX calibration
  Revert "msm: audio: qdsp6v2: Support for out-of-band calibration"
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index 16751fe..a55dee6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -28,9 +28,15 @@
 	uint32_t		cal_paddr;
 };
 
+struct acdb_atomic_cal_block {
+	atomic_t		cal_size;
+	atomic_t		cal_kvaddr;
+	atomic_t		cal_paddr;
+};
+
 struct acdb_cal_data {
-	uint32_t		num_cal_blocks;
-	struct acdb_cal_block	*cal_blocks;
+	uint32_t			num_cal_blocks;
+	struct acdb_atomic_cal_block	*cal_blocks;
 };
 
 uint32_t get_voice_rx_topology(void);
@@ -44,6 +50,7 @@
 void get_all_vocstrm_cal(struct acdb_cal_block *cal_block);
 void get_all_vocvol_cal(struct acdb_cal_block *cal_block);
 void get_anc_cal(struct acdb_cal_block *cal_block);
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
 void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 37a6900..2e61e90 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -22,43 +22,52 @@
 
 #define MAX_NETWORKS		12
 
+struct sidetone_atomic_cal {
+	atomic_t	enable;
+	atomic_t	gain;
+};
+
+
 struct acdb_data {
 	struct mutex		acdb_mutex;
 
 	/* ANC Cal */
-	struct acdb_cal_block	anc_cal;
+	struct acdb_atomic_cal_block	anc_cal;
 
 	/* AudProc Cal */
-	uint32_t		asm_topology;
-	uint32_t		adm_topology[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audproc_cal[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audstrm_cal[MAX_AUDPROC_TYPES];
-	struct acdb_cal_block	audvol_cal[MAX_AUDPROC_TYPES];
+	atomic_t			asm_topology;
+	atomic_t			adm_topology[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audproc_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audstrm_cal[MAX_AUDPROC_TYPES];
+	struct acdb_atomic_cal_block	audvol_cal[MAX_AUDPROC_TYPES];
 
 	/* VocProc Cal */
-	uint32_t                voice_rx_topology;
-	uint32_t                voice_tx_topology;
-	struct acdb_cal_block	vocproc_cal[MAX_NETWORKS];
-	struct acdb_cal_block	vocstrm_cal[MAX_NETWORKS];
-	struct acdb_cal_block	vocvol_cal[MAX_NETWORKS];
+	atomic_t			voice_rx_topology;
+	atomic_t			voice_tx_topology;
+	struct acdb_atomic_cal_block	vocproc_cal[MAX_NETWORKS];
+	struct acdb_atomic_cal_block	vocstrm_cal[MAX_NETWORKS];
+	struct acdb_atomic_cal_block	vocvol_cal[MAX_NETWORKS];
 	/* size of cal block tables above*/
-	uint32_t		vocproc_cal_size;
-	uint32_t		vocstrm_cal_size;
-	uint32_t		vocvol_cal_size;
+	atomic_t			vocproc_cal_size;
+	atomic_t			vocstrm_cal_size;
+	atomic_t			vocvol_cal_size;
 	/* Total size of cal data for all networks */
-	uint32_t		vocproc_total_cal_size;
-	uint32_t		vocstrm_total_cal_size;
-	uint32_t		vocvol_total_cal_size;
+	atomic_t			vocproc_total_cal_size;
+	atomic_t			vocstrm_total_cal_size;
+	atomic_t			vocvol_total_cal_size;
+
+	/* AFE cal */
+	struct acdb_atomic_cal_block	afe_cal[MAX_AUDPROC_TYPES];
 
 	/* Sidetone Cal */
-	struct sidetone_cal	sidetone_cal;
+	struct sidetone_atomic_cal	sidetone_cal;
 
 	/* PMEM information */
-	int			pmem_fd;
-	unsigned long		paddr;
-	unsigned long		kvaddr;
-	unsigned long		pmem_len;
-	struct file		*file;
+	atomic_t			pmem_fd;
+	atomic64_t			paddr;
+	atomic64_t			kvaddr;
+	atomic64_t			pmem_len;
+	struct file			*file;
 
 };
 
@@ -67,90 +76,105 @@
 
 uint32_t get_voice_rx_topology(void)
 {
-	return acdb_data.voice_rx_topology;
+	return atomic_read(&acdb_data.voice_rx_topology);
 }
 
 void store_voice_rx_topology(uint32_t topology)
 {
-	acdb_data.voice_rx_topology = topology;
+	atomic_set(&acdb_data.voice_rx_topology, topology);
 }
 
 uint32_t get_voice_tx_topology(void)
 {
-	return acdb_data.voice_tx_topology;
+	return atomic_read(&acdb_data.voice_tx_topology);
 }
 
 void store_voice_tx_topology(uint32_t topology)
 {
-	acdb_data.voice_tx_topology = topology;
+	atomic_set(&acdb_data.voice_tx_topology, topology);
 }
 
 uint32_t get_adm_rx_topology(void)
 {
-	return acdb_data.adm_topology[RX_CAL];
+	return atomic_read(&acdb_data.adm_topology[RX_CAL]);
 }
 
 void store_adm_rx_topology(uint32_t topology)
 {
-	acdb_data.adm_topology[RX_CAL] = topology;
+	atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
 }
 
 uint32_t get_adm_tx_topology(void)
 {
-	return acdb_data.adm_topology[TX_CAL];
+	return atomic_read(&acdb_data.adm_topology[TX_CAL]);
 }
 
 void store_adm_tx_topology(uint32_t topology)
 {
-	acdb_data.adm_topology[TX_CAL] = topology;
+	atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
 }
 
 uint32_t get_asm_topology(void)
 {
-	return acdb_data.asm_topology;
+	return atomic_read(&acdb_data.asm_topology);
 }
 
 void store_asm_topology(uint32_t topology)
 {
-	acdb_data.asm_topology = topology;
+	atomic_set(&acdb_data.asm_topology, topology);
 }
 
 void get_all_voice_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size +
-				acdb_data.vocstrm_total_cal_size +
-				acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size) +
+		atomic_read(&acdb_data.vocstrm_total_cal_size) +
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_all_cvp_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size +
-				acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size) +
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_all_vocproc_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocproc_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocproc_total_cal_size);
 }
 
 void get_all_vocstrm_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocstrm_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocstrm_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocstrm_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocstrm_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocstrm_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocstrm_total_cal_size);
 }
 
 void get_all_vocvol_cal(struct acdb_cal_block *cal_block)
 {
-	cal_block->cal_kvaddr = acdb_data.vocvol_cal[0].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.vocvol_cal[0].cal_paddr;
-	cal_block->cal_size = acdb_data.vocvol_total_cal_size;
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.vocvol_cal[0].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.vocvol_cal[0].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.vocvol_total_cal_size);
 }
 
 void get_anc_cal(struct acdb_cal_block *cal_block)
@@ -162,13 +186,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.anc_cal.cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.anc_cal.cal_paddr;
-	cal_block->cal_size = acdb_data.anc_cal.cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.anc_cal.cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.anc_cal.cal_size);
 done:
 	return;
 }
@@ -177,23 +200,69 @@
 {
 	pr_debug("%s,\n", __func__);
 
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.anc_cal.cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.anc_cal.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.anc_cal.cal_size,
+		cal_block->cal_size);
+done:
+	return;
+}
 
-	acdb_data.anc_cal.cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.anc_cal.cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.anc_cal.cal_size =
-		cal_block->cal_size;
+void store_afe_cal(int32_t path, struct cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_unlock(&acdb_data.acdb_mutex);
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
+		pr_err("%s: offset %d is > pmem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.pmem_len));
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.afe_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.afe_cal[path].cal_size,
+		cal_block->cal_size);
+done:
+	return;
+}
+
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s, path = %d\n", __func__, path);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+	if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+		pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+			__func__, path);
+		goto done;
+	}
+
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.afe_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.afe_cal[path].cal_size);
 done:
 	return;
 }
@@ -202,12 +271,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -216,15 +283,13 @@
 		goto done;
 	}
 
-	acdb_data.audproc_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audproc_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audproc_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audproc_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -242,13 +307,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audproc_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audproc_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audproc_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audproc_cal[path].cal_size);
 done:
 	return;
 }
@@ -257,12 +321,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -271,15 +333,13 @@
 		goto done;
 	}
 
-	acdb_data.audstrm_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audstrm_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audstrm_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audstrm_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -297,13 +357,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audstrm_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audstrm_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audstrm_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audstrm_cal[path].cal_size);
 done:
 	return;
 }
@@ -312,12 +371,10 @@
 {
 	pr_debug("%s, path = %d\n", __func__, path);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	if (cal_block->cal_offset > acdb_data.pmem_len) {
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
 		pr_err("%s: offset %d is > pmem_len %ld\n",
 			__func__, cal_block->cal_offset,
-			acdb_data.pmem_len);
+			(long)atomic64_read(&acdb_data.pmem_len));
 		goto done;
 	}
 	if (path >= MAX_AUDPROC_TYPES) {
@@ -326,15 +383,13 @@
 		goto done;
 	}
 
-	acdb_data.audvol_cal[path].cal_kvaddr =
-		cal_block->cal_offset + acdb_data.kvaddr;
-	acdb_data.audvol_cal[path].cal_paddr =
-		cal_block->cal_offset + acdb_data.paddr;
-	acdb_data.audvol_cal[path].cal_size =
-		cal_block->cal_size;
-
+	atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+	atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.audvol_cal[path].cal_size,
+		cal_block->cal_size);
 done:
-	mutex_unlock(&acdb_data.acdb_mutex);
 	return;
 }
 
@@ -352,13 +407,12 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_block->cal_kvaddr = acdb_data.audvol_cal[path].cal_kvaddr;
-	cal_block->cal_paddr = acdb_data.audvol_cal[path].cal_paddr;
-	cal_block->cal_size = acdb_data.audvol_cal[path].cal_size;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
+	cal_block->cal_size =
+		atomic_read(&acdb_data.audvol_cal[path].cal_size);
 done:
 	return;
 }
@@ -375,31 +429,28 @@
 		goto done;
 	}
 
-
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocproc_total_cal_size = 0;
+	atomic_set(&acdb_data.vocproc_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocproc_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocproc_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocproc_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocproc_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocproc_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocproc_total_cal_size);
+			atomic_set(&acdb_data.vocproc_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocproc_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocproc_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocproc_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocproc_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocproc_cal_size, len);
 done:
 	return;
 }
@@ -413,12 +464,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocproc_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocproc_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocproc_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -434,30 +481,28 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocstrm_total_cal_size = 0;
+	atomic_set(&acdb_data.vocstrm_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocstrm_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocstrm_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocstrm_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocstrm_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocstrm_total_cal_size);
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocstrm_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocstrm_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocstrm_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocstrm_cal_size, len);
 done:
 	return;
 }
@@ -471,12 +516,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocstrm_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocstrm_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocstrm_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -492,30 +533,28 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.vocvol_total_cal_size = 0;
+	atomic_set(&acdb_data.vocvol_total_cal_size, 0);
 	for (i = 0; i < len; i++) {
-		if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+		if (cal_blocks[i].cal_offset >
+					atomic64_read(&acdb_data.pmem_len)) {
 			pr_err("%s: offset %d is > pmem_len %ld\n",
 				__func__, cal_blocks[i].cal_offset,
-				acdb_data.pmem_len);
-			acdb_data.vocvol_cal[i].cal_size = 0;
+				(long)atomic64_read(&acdb_data.pmem_len));
+			atomic_set(&acdb_data.vocvol_cal[i].cal_size, 0);
 		} else {
-			acdb_data.vocvol_total_cal_size +=
-				cal_blocks[i].cal_size;
-			acdb_data.vocvol_cal[i].cal_size =
-				cal_blocks[i].cal_size;
-			acdb_data.vocvol_cal[i].cal_paddr =
+			atomic_add(cal_blocks[i].cal_size,
+				&acdb_data.vocvol_total_cal_size);
+			atomic_set(&acdb_data.vocvol_cal[i].cal_size,
+				cal_blocks[i].cal_size);
+			atomic_set(&acdb_data.vocvol_cal[i].cal_paddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.paddr;
-			acdb_data.vocvol_cal[i].cal_kvaddr =
+				atomic64_read(&acdb_data.paddr));
+			atomic_set(&acdb_data.vocvol_cal[i].cal_kvaddr,
 				cal_blocks[i].cal_offset +
-				acdb_data.kvaddr;
+				atomic64_read(&acdb_data.kvaddr));
 		}
 	}
-	acdb_data.vocvol_cal_size = len;
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.vocvol_cal_size, len);
 done:
 	return;
 }
@@ -529,12 +568,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->num_cal_blocks = acdb_data.vocvol_cal_size;
+	cal_data->num_cal_blocks = atomic_read(&acdb_data.vocvol_cal_size);
 	cal_data->cal_blocks = &acdb_data.vocvol_cal[0];
-
-	mutex_unlock(&acdb_data.acdb_mutex);
 done:
 	return;
 }
@@ -543,12 +578,8 @@
 {
 	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	acdb_data.sidetone_cal.enable = cal_data->enable;
-	acdb_data.sidetone_cal.gain = cal_data->gain;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
+	atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
 }
 
 
@@ -561,12 +592,8 @@
 		goto done;
 	}
 
-	mutex_lock(&acdb_data.acdb_mutex);
-
-	cal_data->enable = acdb_data.sidetone_cal.enable;
-	cal_data->gain = acdb_data.sidetone_cal.gain;
-
-	mutex_unlock(&acdb_data.acdb_mutex);
+	cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
+	cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
 done:
 	return;
 }
@@ -574,14 +601,12 @@
 static int acdb_open(struct inode *inode, struct file *f)
 {
 	s32 result = 0;
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-	if (acdb_data.pmem_fd) {
-		pr_info("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		pr_debug("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
 			__func__);
 	}
-	mutex_unlock(&acdb_data.acdb_mutex);
 
 	atomic_inc(&usage_count);
 	return result;
@@ -589,9 +614,11 @@
 
 static int deregister_pmem(void)
 {
-	if (acdb_data.pmem_fd) {
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		mutex_lock(&acdb_data.acdb_mutex);
 		put_pmem_file(acdb_data.file);
-		acdb_data.pmem_fd = 0;
+		mutex_unlock(&acdb_data.acdb_mutex);
+		atomic_set(&acdb_data.pmem_fd, 0);
 	}
 	return 0;
 }
@@ -599,19 +626,30 @@
 static int register_pmem(void)
 {
 	int result;
+	unsigned long paddr;
+	unsigned long kvaddr;
+	unsigned long pmem_len;
 
-	result = get_pmem_file(acdb_data.pmem_fd, &acdb_data.paddr,
-				&acdb_data.kvaddr, &acdb_data.pmem_len,
+	mutex_lock(&acdb_data.acdb_mutex);
+	result = get_pmem_file(atomic_read(&acdb_data.pmem_fd),
+				&paddr, &kvaddr, &pmem_len,
 				&acdb_data.file);
+	mutex_unlock(&acdb_data.acdb_mutex);
 	if (result != 0) {
-		acdb_data.pmem_fd = 0;
+		atomic_set(&acdb_data.pmem_fd, 0);
+		atomic64_set(&acdb_data.pmem_len, 0);
 		pr_err("%s: Could not register PMEM!!!\n", __func__);
 		goto done;
 	}
 
+	atomic64_set(&acdb_data.paddr, paddr);
+	atomic64_set(&acdb_data.kvaddr, kvaddr);
+	atomic64_set(&acdb_data.pmem_len, pmem_len);
 	pr_debug("AUDIO_REGISTER_PMEM done! paddr = 0x%lx, "
-		"kvaddr = 0x%lx, len = x%lx\n", acdb_data.paddr,
-		acdb_data.kvaddr, acdb_data.pmem_len);
+		"kvaddr = 0x%lx, len = x%lx\n",
+		(long)atomic64_read(&acdb_data.paddr),
+		(long)atomic64_read(&acdb_data.kvaddr),
+		(long)atomic64_read(&acdb_data.pmem_len));
 
 done:
 	return result;
@@ -619,37 +657,33 @@
 static long acdb_ioctl(struct file *f,
 		unsigned int cmd, unsigned long arg)
 {
-	s32			result = 0;
-	s32			audproc_path;
-	s32			size;
-	u32			topology;
+	int32_t			result = 0;
+	int32_t			size;
+	int32_t			pmem_fd;
+	uint32_t		topology;
 	struct cal_block	data[MAX_NETWORKS];
 	pr_debug("%s\n", __func__);
 
 	switch (cmd) {
 	case AUDIO_REGISTER_PMEM:
 		pr_debug("AUDIO_REGISTER_PMEM\n");
-		mutex_lock(&acdb_data.acdb_mutex);
-		if (acdb_data.pmem_fd) {
+		if (atomic_read(&acdb_data.pmem_fd)) {
 			deregister_pmem();
-			pr_info("Remove the existing PMEM\n");
+			pr_debug("Remove the existing PMEM\n");
 		}
 
-		if (copy_from_user(&acdb_data.pmem_fd, (void *)arg,
-					sizeof(acdb_data.pmem_fd))) {
+		if (copy_from_user(&pmem_fd, (void *)arg, sizeof(pmem_fd))) {
 			pr_err("%s: fail to copy pmem handle!\n", __func__);
 			result = -EFAULT;
 		} else {
+			atomic_set(&acdb_data.pmem_fd, pmem_fd);
 			result = register_pmem();
 		}
-		mutex_unlock(&acdb_data.acdb_mutex);
 		goto done;
 
 	case AUDIO_DEREGISTER_PMEM:
 		pr_debug("AUDIO_DEREGISTER_PMEM\n");
-		mutex_lock(&acdb_data.acdb_mutex);
 		deregister_pmem();
-		mutex_unlock(&acdb_data.acdb_mutex);
 		goto done;
 	case AUDIO_SET_VOICE_RX_TOPOLOGY:
 		if (copy_from_user(&topology, (void *)arg,
@@ -721,45 +755,51 @@
 
 	switch (cmd) {
 	case AUDIO_SET_AUDPROC_TX_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audproc_cal(audproc_path, data);
+		store_audproc_cal(TX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audproc_cal(audproc_path, data);
+		store_audproc_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audstrm_cal(audproc_path, data);
+		store_audstrm_cal(TX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audstrm_cal(audproc_path, data);
+		store_audstrm_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_AUDPROC_TX_VOL_CAL:
-		audproc_path = TX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audvol_cal(audproc_path, data);
+		store_audvol_cal(TX_CAL, data);
 	case AUDIO_SET_AUDPROC_RX_VOL_CAL:
-		audproc_path = RX_CAL;
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
-		store_audvol_cal(audproc_path, data);
+		store_audvol_cal(RX_CAL, data);
+		break;
+	case AUDIO_SET_AFE_TX_CAL:
+		if (size > sizeof(struct cal_block))
+			pr_err("%s: More AFE Cal then expected, "
+				"size received: %d\n", __func__, size);
+		store_afe_cal(TX_CAL, data);
+		break;
+	case AUDIO_SET_AFE_RX_CAL:
+		if (size > sizeof(struct cal_block))
+			pr_err("%s: More AFE Cal then expected, "
+				"size received: %d\n", __func__, size);
+		store_afe_cal(RX_CAL, data);
 		break;
 	case AUDIO_SET_VOCPROC_CAL:
 		store_vocproc_cal(size / sizeof(struct cal_block), data);
@@ -794,14 +834,13 @@
 
 	pr_debug("%s\n", __func__);
 
-	mutex_lock(&acdb_data.acdb_mutex);
-	if (acdb_data.pmem_fd) {
-		if (size <= acdb_data.pmem_len) {
+	if (atomic_read(&acdb_data.pmem_fd)) {
+		if (size <= atomic64_read(&acdb_data.pmem_len)) {
 			vma->vm_page_prot = pgprot_noncached(
 						vma->vm_page_prot);
 			result = remap_pfn_range(vma,
 				vma->vm_start,
-				acdb_data.paddr >> PAGE_SHIFT,
+				atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
 				size,
 				vma->vm_page_prot);
 		} else {
@@ -812,7 +851,6 @@
 		pr_err("%s: PMEM is not allocated, yet!\n", __func__);
 		result = -ENODEV;
 	}
-	mutex_unlock(&acdb_data.acdb_mutex);
 
 	return result;
 }
@@ -824,16 +862,13 @@
 	atomic_dec(&usage_count);
 	atomic_read(&usage_count);
 
-	pr_info("%s: ref count %d!\n", __func__,
+	pr_debug("%s: ref count %d!\n", __func__,
 		atomic_read(&usage_count));
 
-	if (atomic_read(&usage_count) >= 1) {
+	if (atomic_read(&usage_count) >= 1)
 		result = -EBUSY;
-	} else {
-		mutex_lock(&acdb_data.acdb_mutex);
+	else
 		result = deregister_pmem();
-		mutex_unlock(&acdb_data.acdb_mutex);
-	}
 
 	return result;
 }
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 34169c0..12a02c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -791,7 +791,7 @@
 	struct apr_hdr cvs_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
 	int index = 0;
@@ -830,11 +830,12 @@
 	pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
 		pr_debug(" cal size =%d\n", cal_size_per_network);
 		if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
 			pr_err("Cal size is too big\n");
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 		pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
 		cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 			cal_size_per_network);
@@ -868,7 +869,7 @@
 	struct apr_hdr cvp_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
 	int index = 0;
@@ -907,11 +908,12 @@
 	pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
 		if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
 			pr_err("Cal size is too big\n");
 		pr_debug(" cal size =%d\n", cal_size_per_network);
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 		pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
 
 		cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
@@ -945,11 +947,9 @@
 	struct apr_hdr cvp_vol_cal_cmd_hdr;
 	uint32_t *cmd_buf;
 	struct acdb_cal_data cal_data;
-	struct acdb_cal_block *cal_blk;
+	struct acdb_atomic_cal_block *cal_blk;
 	int32_t cal_size_per_network;
 	uint32_t *cal_data_per_network;
-	uint32_t num_volume_steps;
-	int offset = 0;
 	int index = 0;
 	int ret = 0;
 	void *apr_cvp = voice_get_apr_cvp();
@@ -986,27 +986,18 @@
 	pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
 
 	for (; index < cal_data.num_cal_blocks; index++) {
-		cal_size_per_network = cal_blk[index].cal_size;
-		cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
-
-		/* Number of volume steps are only included in the */
-		/* first block, need to be inserted into the rest */
-		if (index != 0) {
-			offset = sizeof(num_volume_steps);
-			memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
-				&num_volume_steps, offset);
-		} else {
-			num_volume_steps = *cal_data_per_network;
-		}
+		cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
+		cal_data_per_network =
+			(u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
 
 		pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
 			index);
 		pr_debug("Cal data=%x\n", (uint32_t)cal_data_per_network);
 		cvp_vol_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
-			cal_size_per_network + offset);
+			cal_size_per_network);
 		memcpy(cmd_buf, &cvp_vol_cal_cmd_hdr,  APR_HDR_SIZE);
-		memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)) +
-			offset, cal_data_per_network, cal_size_per_network);
+		memcpy(cmd_buf + (APR_HDR_SIZE / sizeof(uint32_t)),
+			cal_data_per_network, cal_size_per_network);
 		pr_debug("Send vol table\n");
 
 		v->cvp_state = CMD_STATUS_FAIL;
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index 3d756c2..e7f06b5 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -35,6 +35,13 @@
 			(AUDIO_MAX_COMMON_IOCTL_NUM+14), unsigned)
 #define AUDIO_SET_ASM_TOPOLOGY	_IOW(AUDIO_IOCTL_MAGIC, \
 			(AUDIO_MAX_COMMON_IOCTL_NUM+15), unsigned)
+#define AUDIO_SET_AFE_TX_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+#define AUDIO_SET_AFE_RX_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+
+
+#define	AUDIO_MAX_ACDB_IOCTL	(AUDIO_MAX_COMMON_IOCTL_NUM+30)
 
 /* ACDB structures */
 struct cal_block {
@@ -49,25 +56,26 @@
 
 /* For Real-Time Audio Calibration */
 #define AUDIO_GET_RTAC_ADM_INFO		_IOR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+1), unsigned)
 #define AUDIO_GET_RTAC_VOICE_INFO	_IOR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+2), unsigned)
 #define AUDIO_GET_RTAC_ADM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+18), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+3), unsigned)
 #define AUDIO_SET_RTAC_ADM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+19), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+4), unsigned)
 #define AUDIO_GET_RTAC_ASM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+20), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+5), unsigned)
 #define AUDIO_SET_RTAC_ASM_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+21), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+6), unsigned)
 #define AUDIO_GET_RTAC_CVS_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+22), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+7), unsigned)
 #define AUDIO_SET_RTAC_CVS_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+23), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+8), unsigned)
 #define AUDIO_GET_RTAC_CVP_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+24), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+9), unsigned)
 #define AUDIO_SET_RTAC_CVP_CAL	_IOWR(AUDIO_IOCTL_MAGIC, \
-			(AUDIO_MAX_COMMON_IOCTL_NUM+25), unsigned)
+			(AUDIO_MAX_ACDB_IOCTL+10), unsigned)
 
+#define	AUDIO_MAX_RTAC_IOCTL	(AUDIO_MAX_ACDB_IOCTL+20)
 
 #endif /* __MSM_AUDIO_ACDB_H */
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 798ed89..30f1a7c 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1,7 +1,6 @@
-
 /*
  *
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -353,6 +352,12 @@
 	struct afe_param_payload payload;
 } __attribute__ ((packed));
 
+struct afe_port_cmd_set_param_no_payload {
+	struct apr_hdr hdr;
+	u16 port_id;
+	u16 payload_size;
+	u32 payload_address;
+} __packed;
 
 #define AFE_EVENT_GET_ACTIVE_PORTS 0x00010100
 struct afe_get_active_ports_rsp {
diff --git a/include/sound/q6afe.h b/include/sound/q6afe.h
index 6206838..2d0f53f 100644
--- a/include/sound/q6afe.h
+++ b/include/sound/q6afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -76,7 +76,9 @@
 int afe_start_pseudo_port(u16 port_id);
 int afe_stop_pseudo_port(u16 port_id);
 int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz);
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz);
 int afe_cmd_memory_unmap(u32 dma_addr_p);
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p);
 
 int afe_register_get_events(u16 port_id,
 		void (*cb) (uint32_t opcode,
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 18dfc01..d8d9c64 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -457,7 +457,7 @@
 	int     i = 0;
 	int     cmd_size = 0;
 
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 	if (this_adm.apr == NULL) {
 		this_adm.apr = apr_register("ADSP", "ADM", adm_callback,
 						0xFFFFFFFF, &this_adm);
@@ -532,7 +532,7 @@
 	int     i = 0;
 	int     cmd_size = 0;
 
-	pr_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	if (this_adm.apr == NULL) {
 		pr_err("%s APR handle NULL\n", __func__);
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 74a66945..a214529 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -17,6 +17,7 @@
 #include <linux/wait.h>
 #include <linux/jiffies.h>
 #include <linux/sched.h>
+#include <mach/qdsp6v2/audio_acdb.h>
 #include <sound/apr_audio.h>
 #include <sound/q6afe.h>
 
@@ -36,6 +37,8 @@
 
 static struct afe_ctl this_afe;
 
+static uint32_t afe_cal_addr[MAX_AUDPROC_TYPES];
+
 #define TIMEOUT_MS 1000
 #define Q6AFE_MAX_VOLUME 0x3FFF
 
@@ -314,6 +317,63 @@
 	return ret;
 }
 
+static void afe_send_cal_block(int32_t path, u16 port_id)
+{
+	int						result = 0;
+	struct acdb_cal_block				cal_block;
+	struct afe_port_cmd_set_param_no_payload	afe_cal;
+	pr_debug("%s: path %d\n", __func__, path);
+
+	get_afe_cal(path, &cal_block);
+	if (cal_block.cal_size <= 0) {
+		pr_debug("%s: No AFE cal to send!\n", __func__);
+		goto done;
+	}
+
+	if (afe_cal_addr[path] != cal_block.cal_paddr) {
+		if (afe_cal_addr[path] != 0)
+			afe_cmd_memory_unmap_nowait(afe_cal_addr[path]);
+		afe_cmd_memory_map_nowait(cal_block.cal_paddr,
+						cal_block.cal_size);
+		afe_cal_addr[path] = cal_block.cal_paddr;
+	}
+
+	afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	afe_cal.hdr.pkt_size = sizeof(afe_cal);
+	afe_cal.hdr.src_port = 0;
+	afe_cal.hdr.dest_port = 0;
+	afe_cal.hdr.token = 0;
+	afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM;
+	afe_cal.port_id = port_id;
+	afe_cal.payload_size = cal_block.cal_size;
+	afe_cal.payload_address = cal_block.cal_paddr;
+
+	pr_debug("%s: AFE cal sent for device port = %d, path = %d, "
+		"cal size = %d, cal addr = 0x%x\n", __func__,
+		port_id, path, cal_block.cal_size, cal_block.cal_paddr);
+
+	result = apr_send_pkt(this_afe.apr, (uint32_t *) &afe_cal);
+	if (result < 0) {
+		pr_err("%s: AFE cal for port %d failed\n",
+			__func__, port_id);
+	}
+
+	pr_debug("%s: AFE cal sent for path %d device!\n", __func__, path);
+done:
+	return;
+}
+
+void afe_send_cal(u16 port_id)
+{
+	pr_debug("%s\n", __func__);
+
+	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
+		afe_send_cal_block(TX_CAL, port_id);
+	else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX)
+		afe_send_cal_block(RX_CAL, port_id);
+}
+
 int afe_port_start_nowait(u16 port_id, union afe_port_config *afe_config,
 	u32 rate) /* This function is no blocking */
 {
@@ -365,6 +425,10 @@
 		ret = -EINVAL;
 		goto fail_cmd;
 	}
+
+	/* send AFE cal */
+	afe_send_cal(port_id);
+
 	start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	start.hdr.pkt_size = sizeof(start);
@@ -875,6 +939,45 @@
 	return 0;
 }
 
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz)
+{
+	int ret = 0;
+	struct afe_cmd_memory_map mregion;
+
+	pr_debug("%s:\n", __func__);
+
+	if (this_afe.apr == NULL) {
+		this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+					0xFFFFFFFF, &this_afe);
+		pr_debug("%s: Register AFE\n", __func__);
+		if (this_afe.apr == NULL) {
+			pr_err("%s: Unable to register AFE\n", __func__);
+			ret = -ENODEV;
+			return ret;
+		}
+	}
+
+	mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	mregion.hdr.pkt_size = sizeof(mregion);
+	mregion.hdr.src_port = 0;
+	mregion.hdr.dest_port = 0;
+	mregion.hdr.token = 0;
+	mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_MAP;
+	mregion.phy_addr = dma_addr_p;
+	mregion.mem_sz = dma_buf_sz;
+	mregion.mem_id = 0;
+	mregion.rsvd = 0;
+
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+	if (ret < 0) {
+		pr_err("%s: AFE memory map cmd failed %d\n",
+			__func__, ret);
+		ret = -EINVAL;
+	}
+	return 0;
+}
+
 int afe_cmd_memory_unmap(u32 dma_addr_p)
 {
 	int ret = 0;
@@ -905,7 +1008,7 @@
 	atomic_set(&this_afe.state, 1);
 	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
 	if (ret < 0) {
-		pr_err("%s: AFE memory map cmd failed %d\n",
+		pr_err("%s: AFE memory unmap cmd failed %d\n",
 		       __func__, ret);
 		ret = -EINVAL;
 		return ret;
@@ -919,7 +1022,42 @@
 		ret = -EINVAL;
 		return ret;
 	}
+	return 0;
+}
 
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p)
+{
+	int ret = 0;
+	struct afe_cmd_memory_unmap mregion;
+
+	pr_debug("%s:\n", __func__);
+
+	if (this_afe.apr == NULL) {
+		this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+					0xFFFFFFFF, &this_afe);
+		pr_debug("%s: Register AFE\n", __func__);
+		if (this_afe.apr == NULL) {
+			pr_err("%s: Unable to register AFE\n", __func__);
+			ret = -ENODEV;
+			return ret;
+		}
+	}
+
+	mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	mregion.hdr.pkt_size = sizeof(mregion);
+	mregion.hdr.src_port = 0;
+	mregion.hdr.dest_port = 0;
+	mregion.hdr.token = 0;
+	mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_UNMAP;
+	mregion.phy_addr = dma_addr_p;
+
+	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+	if (ret < 0) {
+		pr_err("%s: AFE memory unmap cmd failed %d\n",
+			__func__, ret);
+		ret = -EINVAL;
+	}
 	return 0;
 }
 
@@ -1389,12 +1527,17 @@
 
 static void __exit afe_exit(void)
 {
+	int i;
 #ifdef CONFIG_DEBUG_FS
 	if (debugfs_afelb)
 		debugfs_remove(debugfs_afelb);
 	if (debugfs_afelb_gain)
 		debugfs_remove(debugfs_afelb_gain);
 #endif
+	for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
+		if (afe_cal_addr[i] != 0)
+			afe_cmd_memory_unmap_nowait(afe_cal_addr[i]);
+	}
 }
 
 device_initcall(afe_init);