ASoC: msm: Add timestamp support for compressed audio

The timestamp would be used by applications for AVSYNC purpose.

Change-Id: I416c38e82fbd51b58df119c0122bcd629ccd88fd
Signed-off-by: Asish Bhattacharya <asishb@codeaurora.org>
diff --git a/include/sound/compress_offload.h b/include/sound/compress_offload.h
index 423264d..f746780 100644
--- a/include/sound/compress_offload.h
+++ b/include/sound/compress_offload.h
@@ -56,6 +56,7 @@
 	size_t decoded;
 	size_t rendered;
 	__u32 sampling_rate;
+	uint64_t timestamp;
 };
 
 /**
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 6dd815d..8c07206 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1530,8 +1530,6 @@
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
 	runtime = substream->runtime;
-	if (runtime->status->state != SNDRV_PCM_STATE_OPEN)
-		return -EBADFD;
 	pr_err("%s called with cmd = %d\n", __func__, cmd);
 	err = substream->ops->ioctl(substream, cmd, arg);
 	return err;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index d0497b1..f0f17a9 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -450,8 +450,37 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct compr_audio *compr = runtime->private_data;
 	struct msm_audio *prtd = &compr->prtd;
+	uint64_t timestamp;
+	uint64_t temp;
 
 	switch (cmd) {
+	case SNDRV_COMPRESS_TSTAMP: {
+		struct snd_compr_tstamp tstamp;
+		pr_debug("SNDRV_COMPRESS_TSTAMP\n");
+
+		memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
+		timestamp = q6asm_get_session_time(prtd->audio_client);
+		if (timestamp < 0) {
+			pr_err("%s: Get Session Time return value =%lld\n",
+				__func__, timestamp);
+			return -EAGAIN;
+		}
+		temp = (timestamp * 2 * runtime->channels);
+		temp = temp * (runtime->rate/1000);
+		temp = div_u64(temp, 1000);
+		tstamp.sampling_rate = runtime->rate;
+		tstamp.rendered = (size_t)(temp & 0xFFFFFFFF);
+		tstamp.decoded  = (size_t)((temp >> 32) & 0xFFFFFFFF);
+		tstamp.timestamp = timestamp;
+		pr_debug("%s: bytes_consumed:lsb = %d, msb = %d,"
+			"timestamp = %lld,\n",
+			 __func__, tstamp.rendered, tstamp.decoded,
+			tstamp.timestamp);
+		if (copy_to_user((void *) arg, &tstamp,
+			sizeof(struct snd_compr_tstamp)))
+				return -EFAULT;
+		return 0;
+	}
 	case SNDRV_COMPRESS_GET_CAPS:
 		pr_debug("SNDRV_COMPRESS_GET_CAPS\n");
 		if (copy_to_user((void *) arg, &compr->info.compr_cap,