Merge "ASoC: msm : DTS security implementation"
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
similarity index 81%
rename from arch/arm/mach-msm/qdsp6v2/q6core.h
rename to arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
index cb25d6b..ea345fb 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -45,8 +45,18 @@
 	uint32_t power_collapse;
 };
 
+#define ADSP_CMD_SET_DTS_MODEL_ID 0x00012917
+
+struct adsp_dts_modelid {
+	struct apr_hdr hdr;
+	uint32_t  model_ID_size;
+	uint8_t   model_ID[128];
+};
+
 int core_req_bus_bandwith(u16 bus_id, u32 ab_bps, u32 ib_bps);
 
 uint32_t core_get_adsp_version(void);
 
+uint32_t core_set_dts_model_id(uint32_t id_size, uint8_t *id);
+
 #endif /* __Q6CORE_H__ */
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index c19fd85..63b3064 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -26,7 +26,7 @@
 #include <mach/msm_hdmi_audio.h>
 #include <mach/audio_dma_msm8k.h>
 #include <sound/dai.h>
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
 
 #define DMA_ALLOC_BUF_SZ		(SZ_4K * 16)
 
diff --git a/arch/arm/mach-msm/qdsp6v2/q6core.c b/arch/arm/mach-msm/qdsp6v2/q6core.c
index d7de50e..9dd66e1 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6core.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6core.c
@@ -26,7 +26,7 @@
 #include <linux/delay.h>
 #include <mach/msm_smd.h>
 #include <mach/qdsp6v2/apr.h>
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
 
 #define TIMEOUT_MS 1000
 
@@ -79,6 +79,10 @@
 			bus_bw_resp_received = 1;
 			wake_up(&bus_bw_req_wait);
 			break;
+		case ADSP_CMD_SET_DTS_MODEL_ID:
+			pr_debug("ADSP_CMD_SET_DTS_MODEL_ID status[0x%x]\n",
+					payload1[1]);
+			break;
 		default:
 			pr_err("Invalid cmd rsp[0x%x][0x%x]\n",
 					payload1[0], payload1[1]);
@@ -382,6 +386,35 @@
 	return count;
 }
 
+uint32_t core_set_dts_model_id(uint32_t id_size, uint8_t *id)
+{
+	struct adsp_dts_modelid payload;
+	int rc = 0;
+	pr_debug("core_set_dts_model_id(): Enter\n");
+	core_open();
+	if (core_handle_q) {
+		payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
+			APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+		payload.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+					sizeof(uint32_t)+id_size);
+		payload.hdr.src_port = 0;
+		payload.hdr.dest_port = 0;
+		payload.hdr.token = 0;
+		payload.hdr.opcode = ADSP_CMD_SET_DTS_MODEL_ID;
+		payload.model_ID_size = id_size;
+		memcpy(payload.model_ID, id, id_size+1);
+		pr_debug("Send DTS sec opcode=%x modelID = %s, size=%d\n",
+			payload.hdr.opcode, (char *)payload.model_ID,
+			payload.model_ID_size);
+		rc = apr_send_pkt(core_handle_q, (uint32_t *)&payload);
+		if (rc < 0)
+			pr_err("%s: SET_DTS_DTS_MODEL_ID failed op[0x%x]rc[%d]\n",
+				__func__, payload.hdr.opcode, rc);
+	}
+	pr_debug("core_set_dts_model_id(): Exit\n");
+	return rc;
+}
+
 static const struct file_operations apr_debug_fops = {
 	.write = apr_debug_write,
 	.open = apr_debug_open,
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 12a02c5..7464ed7 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -30,7 +30,7 @@
 #include <mach/qdsp6v2/rtac.h>
 #include <mach/qdsp6v2/audio_acdb.h>
 
-#include "q6core.h"
+#include <mach/qdsp6v2/q6core.h>
 
 
 #define TIMEOUT_MS 3000
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index 0daceca..54af7d6a 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -332,6 +332,10 @@
 	__u32 bw;	/* encoder bandwidth */
 	__s32 reserved[15];
 };
+struct snd_dec_dts {
+	__u32 modelIdLength;
+	__u8 *modelId;
+};
 
 union snd_codec_options {
 	struct snd_enc_wma wma;
@@ -339,6 +343,7 @@
 	struct snd_enc_real real;
 	struct snd_enc_flac flac;
 	struct snd_enc_generic generic;
+	struct snd_dec_dts dts;
 };
 
 /** struct snd_codec_desc - description of codec capabilities
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index a9b029f..172b02c 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -31,6 +31,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/android_pmem.h>
 #include <sound/timer.h>
+#include <mach/qdsp6v2/q6core.h>
 
 #include "msm-compr-q6.h"
 #include "msm-pcm-routing.h"
@@ -1079,13 +1080,37 @@
 			pr_debug("SND_AUDIOCODEC_DTS_PASS_THROUGH\n");
 			compr->codec = FORMAT_DTS;
 			break;
-		case SND_AUDIOCODEC_DTS:
+		case SND_AUDIOCODEC_DTS: {
+			char modelId[128];
+			struct snd_dec_dts opt_dts =
+				compr->info.codec_param.codec.options.dts;
+			int modelIdLength = opt_dts.modelIdLength;
 			pr_debug("SND_AUDIOCODEC_DTS\n");
+			if (copy_from_user(modelId, (void *)opt_dts.modelId,
+				modelIdLength))
+				pr_err("%s: ERROR: copy modelId\n", __func__);
+			modelId[modelIdLength] = '\0';
+			pr_debug("%s: Received modelId =%s,length=%d\n",
+				__func__, modelId, modelIdLength);
+			core_set_dts_model_id(modelIdLength, modelId);
 			compr->codec = FORMAT_DTS;
+			}
 			break;
-		case SND_AUDIOCODEC_DTS_LBR:
-			pr_debug("SND_AUDIOCODEC_DTS\n");
+		case SND_AUDIOCODEC_DTS_LBR:{
+			char modelId[128];
+			struct snd_dec_dts opt_dts =
+				compr->info.codec_param.codec.options.dts;
+			int modelIdLength = opt_dts.modelIdLength;
+			pr_debug("SND_AUDIOCODEC_DTS_LBR\n");
+			if (copy_from_user(modelId, (void *)opt_dts.modelId,
+					modelIdLength))
+				pr_err("%s: ERROR: copy modelId\n", __func__);
+			modelId[modelIdLength] = '\0';
+			pr_debug("%s: Received modelId =%s,length=%d\n",
+				__func__, modelId, modelIdLength);
+			core_set_dts_model_id(modelIdLength, modelId);
 			compr->codec = FORMAT_DTS_LBR;
+			}
 			break;
 		case SND_AUDIOCODEC_AMRWB:
 			pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWB\n");
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 1e75c53..b086b8e 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -875,8 +875,9 @@
 		case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
 			if (atomic_read(&ac->cmd_state) && wakeup_flag) {
 				atomic_set(&ac->cmd_state, 0);
-				if (payload[1] == ADSP_EUNSUPPORTED) {
-					pr_debug("paload[1]:%d unsupported",
+				if (payload[1] == ADSP_EUNSUPPORTED ||
+					payload[1] == ADSP_EFAILED) {
+					pr_debug("payload[1]:%d unsupported",
 								payload[1]);
 					atomic_set(&ac->cmd_response, 1);
 				}