Merge "ASoC: msm8974: Add listen calibration support"
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index e907f4a..471f10a 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -1,5 +1,5 @@
-#ifndef __MSM_AUDIO_ACDB_H
-#define __MSM_AUDIO_ACDB_H
+#ifndef _LINUX_MSM_AUDIO_ACDB_H
+#define _LINUX_MSM_AUDIO_ACDB_H
 
 #include <linux/msm_audio.h>
 
@@ -47,6 +47,8 @@
 			(AUDIO_MAX_COMMON_IOCTL_NUM+20), unsigned)
 #define AUDIO_SET_VOCPROC_DEV_CFG_CAL	_IOW(AUDIO_IOCTL_MAGIC, \
 			(AUDIO_MAX_COMMON_IOCTL_NUM+21), unsigned)
+#define AUDIO_SET_LSM_CAL		_IOW(AUDIO_IOCTL_MAGIC, \
+			(AUDIO_MAX_COMMON_IOCTL_NUM+22), unsigned)
 
 #define	AUDIO_MAX_ACDB_IOCTL	(AUDIO_MAX_COMMON_IOCTL_NUM+30)
 
@@ -85,4 +87,4 @@
 
 #define	AUDIO_MAX_RTAC_IOCTL	(AUDIO_MAX_ACDB_IOCTL+20)
 
-#endif /* __MSM_AUDIO_ACDB_H */
+#endif /* _LINUX_MSM_AUDIO_ACDB_H */
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index 7061efa..58fdc1b 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -42,6 +42,9 @@
 	/* ANC Cal */
 	struct acdb_atomic_cal_block	anc_cal;
 
+	/* LSM Cal */
+	struct acdb_atomic_cal_block	lsm_cal;
+
 	/* AudProc Cal */
 	atomic_t			asm_topology;
 	atomic_t			adm_topology[MAX_AUDPROC_TYPES];
@@ -140,6 +143,46 @@
 		atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
 }
 
+void get_lsm_cal(struct acdb_cal_block *cal_block)
+{
+	pr_debug("%s\n", __func__);
+
+	if (cal_block == NULL) {
+		pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+		goto done;
+	}
+
+	cal_block->cal_size =
+		atomic_read(&acdb_data.lsm_cal.cal_size);
+	cal_block->cal_paddr =
+		atomic_read(&acdb_data.lsm_cal.cal_paddr);
+	cal_block->cal_kvaddr =
+		atomic_read(&acdb_data.lsm_cal.cal_kvaddr);
+done:
+	return;
+}
+
+void store_lsm_cal(struct cal_block *cal_block)
+{
+	pr_debug("%s,\n", __func__);
+
+	if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
+		pr_err("%s: offset %d is > mem_len %ld\n",
+			__func__, cal_block->cal_offset,
+			(long)atomic64_read(&acdb_data.mem_len));
+		goto done;
+	}
+
+	atomic_set(&acdb_data.lsm_cal.cal_size,
+		cal_block->cal_size);
+	atomic_set(&acdb_data.lsm_cal.cal_paddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+	atomic_set(&acdb_data.lsm_cal.cal_kvaddr,
+		cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+done:
+	return;
+}
+
 void get_anc_cal(struct acdb_cal_block *cal_block)
 {
 	pr_debug("%s\n", __func__);
@@ -879,6 +922,9 @@
 	case AUDIO_SET_ANC_CAL:
 		store_anc_cal((struct cal_block *)data);
 		goto done;
+	case AUDIO_SET_LSM_CAL:
+		store_lsm_cal((struct cal_block *)data);
+		goto done;
 	default:
 		pr_err("ACDB=> ACDB ioctl not found!\n");
 	}
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
index c31823b..8528e3c 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.h
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -47,6 +47,7 @@
 uint32_t get_adm_tx_topology(void);
 uint32_t get_asm_topology(void);
 void get_voice_cal_allocation(struct acdb_cal_block *cal_block);
+void get_lsm_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);