msm: audio: qdsp6v2: Add codec support in mvs driver
Support for Qcelp-13k, EFR, FR, HR, G.711 modes in mvs driver.
Change-Id: I5b8f90388b2fc79ad6d9b6276d0dd29e3cc6ba80
Signed-off-by: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index 1f8ce68..674cfe8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -521,6 +521,8 @@
#define VSS_NETWORK_ID_VOIP_WV 0x00011242
/* Media types */
+#define VSS_MEDIA_ID_13K_MODEM 0x00010FC1
+/* Qcelp vocoder modem format */
#define VSS_MEDIA_ID_EVRC_MODEM 0x00010FC2
/* 80-VF690-47 CDMA enhanced variable rate vocoder modem format. */
#define VSS_MEDIA_ID_4GV_NB_MODEM 0x00010FC3
@@ -531,6 +533,12 @@
/* 80-VF690-47 UMTS AMR-NB vocoder modem format. */
#define VSS_MEDIA_ID_AMR_WB_MODEM 0x00010FC7
/* 80-VF690-47 UMTS AMR-WB vocoder modem format. */
+#define VSS_MEDIA_ID_EFR_MODEM 0x00010FC8
+/*EFR modem format */
+#define VSS_MEDIA_ID_FR_MODEM 0x00010FC9
+/*FR modem format */
+#define VSS_MEDIA_ID_HR_MODEM 0x00010FCA
+/*HR modem format */
#define VSS_MEDIA_ID_PCM_NB 0x00010FCB
/* Linear PCM (16-bit, little-endian). */
#define VSS_MEDIA_ID_PCM_WB 0x00010FCC
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index 0b4997c..6e7961c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -205,6 +205,7 @@
break;
}
+ case MVS_MODE_G711:
case MVS_MODE_G711A: {
/* G711 frames are 10ms each, but the DSP works with
* 20ms frames and sends two 10ms frames per buffer.
@@ -212,11 +213,16 @@
* buffers.
*/
/* Remove the first DSP frame info header.
- * Header format:
+ * Header format: G711A
* Bits 0-1: Frame type
* Bits 2-3: Frame rate
+ *
+ * Header format: G711
+ * Bits 2-3: Frame rate
*/
- buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
+ if (audio->mvs_mode == MVS_MODE_G711A)
+ buf_node->frame.header.frame_type =
+ (*voc_pkt) & 0x03;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
/* There are two frames in the buffer. Length of the
@@ -247,7 +253,8 @@
* Bits 0-1: Frame type
* Bits 2-3: Frame rate
*/
- buf_node->frame.header.frame_type =
+ if (audio->mvs_mode == MVS_MODE_G711A)
+ buf_node->frame.header.frame_type =
(*voc_pkt) & 0x03;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
@@ -271,6 +278,7 @@
break;
}
+ case MVS_MODE_IS733:
case MVS_MODE_4GV_NB:
case MVS_MODE_4GV_WB: {
/* Remove the DSP frame info header.
@@ -284,6 +292,32 @@
memcpy(&buf_node->frame.voc_pkt[0],
voc_pkt,
buf_node->frame.len);
+
+ list_add_tail(&buf_node->list, &audio->out_queue);
+ break;
+ }
+
+ case MVS_MODE_EFR:
+ case MVS_MODE_FR:
+ case MVS_MODE_HR: {
+ /*
+ * Remove the DSP frame info header
+ * Header Format
+ * Bit 0: bfi unused for uplink
+ * Bit 1-2: sid applies to both uplink and downlink
+ * Bit 3: taf unused for uplink
+ * MVS_MODE_HR
+ * Bit 4: ufi unused for uplink
+ */
+ buf_node->frame.header.gsm_frame_type.sid =
+ ((*voc_pkt) & 0x06) >> 1;
+ voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+ buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
+
+ memcpy(&buf_node->frame.voc_pkt[0],
+ voc_pkt,
+ buf_node->frame.len);
+
list_add_tail(&buf_node->list, &audio->out_queue);
break;
}
@@ -353,7 +387,6 @@
case MVS_MODE_IS127: {
/* Add the DSP frame info header. Header format:
* Bits 0-3: Frame rate
- * Bits 4-7: Frame type
*/
*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
@@ -423,6 +456,7 @@
break;
}
+ case MVS_MODE_G711:
case MVS_MODE_G711A: {
/* G711 frames are 10ms each but the DSP expects 20ms
* worth of data, so send two 10ms frames per buffer.
@@ -481,6 +515,7 @@
break;
}
+ case MVS_MODE_IS733:
case MVS_MODE_4GV_NB:
case MVS_MODE_4GV_WB: {
/* Add the DSP frame info header. Header format:
@@ -498,6 +533,48 @@
break;
}
+ case MVS_MODE_EFR:
+ case MVS_MODE_FR:
+ case MVS_MODE_HR: {
+ /*
+ * Remove the DSP frame info header
+ * Header Format
+ * Bit 0: bfi applies only for downlink
+ * Bit 1-2: sid applies for downlink and uplink
+ * Bit 3: taf applies only for downlink
+ * MVS_MODE_HR
+ * Bit 4: ufi applies only for downlink
+ */
+ *voc_pkt =
+ ((buf_node->frame.header.gsm_frame_type.bfi
+ & 0x01) |
+ ((buf_node->frame.header.gsm_frame_type.sid
+ & 0x03) << 1) |
+ ((buf_node->frame.header.gsm_frame_type.taf
+ & 0x01) << 3));
+
+ if (audio->mvs_mode == MVS_MODE_HR) {
+ *voc_pkt = (*voc_pkt |
+ ((buf_node->frame.header.gsm_frame_type.ufi
+ & 0x01) << 4) |
+ ((0 & 0x07) << 5));
+ } else {
+ *voc_pkt = (*voc_pkt |
+ ((0 & 0x0F) << 4));
+ }
+
+ voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+ *pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
+
+ memcpy(voc_pkt,
+ &buf_node->frame.voc_pkt[0],
+ buf_node->frame.len);
+
+ list_add_tail(&buf_node->list, &audio->free_in_queue);
+
+ break;
+ }
+
default: {
*pkt_len = buf_node->frame.len;
@@ -523,6 +600,10 @@
uint32_t media_type;
switch (mvs_mode) {
+ case MVS_MODE_IS733:
+ media_type = VSS_MEDIA_ID_13K_MODEM;
+ break;
+
case MVS_MODE_IS127:
media_type = VSS_MEDIA_ID_EVRC_MODEM;
break;
@@ -539,6 +620,18 @@
media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
break;
+ case MVS_MODE_EFR:
+ media_type = VSS_MEDIA_ID_EFR_MODEM;
+ break;
+
+ case MVS_MODE_FR:
+ media_type = VSS_MEDIA_ID_FR_MODEM;
+ break;
+
+ case MVS_MODE_HR:
+ media_type = VSS_MEDIA_ID_HR_MODEM;
+ break;
+
case MVS_MODE_LINEAR_PCM:
media_type = VSS_MEDIA_ID_PCM_NB;
break;
@@ -555,6 +648,7 @@
media_type = VSS_MEDIA_ID_G729;
break;
+ case MVS_MODE_G711:
case MVS_MODE_G711A:
if (rate_type == MVS_G711A_MODE_MULAW)
media_type = VSS_MEDIA_ID_G711_MULAW;
@@ -580,10 +674,15 @@
uint32_t network_type;
switch (mvs_mode) {
+ case MVS_MODE_IS733:
case MVS_MODE_IS127:
case MVS_MODE_4GV_NB:
case MVS_MODE_AMR:
+ case MVS_MODE_EFR:
+ case MVS_MODE_FR:
+ case MVS_MODE_HR:
case MVS_MODE_LINEAR_PCM:
+ case MVS_MODE_G711:
case MVS_MODE_PCM:
case MVS_MODE_G729A:
case MVS_MODE_G711A:
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 058e281..34169c0 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1117,6 +1117,7 @@
/* Set encoder properties. */
switch (common.mvs_info.media_type) {
+ case VSS_MEDIA_ID_13K_MODEM:
case VSS_MEDIA_ID_4GV_NB_MODEM:
case VSS_MEDIA_ID_4GV_WB_MODEM:
case VSS_MEDIA_ID_EVRC_MODEM: {
@@ -1253,6 +1254,9 @@
break;
}
+ case VSS_MEDIA_ID_EFR_MODEM:
+ case VSS_MEDIA_ID_FR_MODEM:
+ case VSS_MEDIA_ID_HR_MODEM:
case VSS_MEDIA_ID_G729:
case VSS_MEDIA_ID_G711_ALAW:
case VSS_MEDIA_ID_G711_MULAW: {
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index c934aee..2813c8f 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -108,10 +108,18 @@
#define MVS_MAX_VOC_PKT_SIZE 640
+struct gsm_header {
+ uint8_t bfi;
+ uint8_t sid;
+ uint8_t taf;
+ uint8_t ufi;
+};
+
struct q6_msm_audio_mvs_frame {
union {
uint32_t frame_type;
uint32_t packet_rate;
+ struct gsm_header gsm_frame_type;
} header;
uint32_t len;
uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE];