msm: audio: qdsp6v2: Add 4GV wb/nb support in mvs driver
Support for 4GV-wb mode and 4GV-nb mode in mvs driver
and add support for min-max rate.
Change-Id: Iacd33ecfbdf278eb59b3e662c725d21fb60e4ab3
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 fb6e22e..1f8ce68 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -523,6 +523,10 @@
/* Media types */
#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
+/* 4GV Narrowband modem format */
+#define VSS_MEDIA_ID_4GV_WB_MODEM 0x00010FC4
+/* 4GV Wideband modem format */
#define VSS_MEDIA_ID_AMR_NB_MODEM 0x00010FC6
/* 80-VF690-47 UMTS AMR-NB vocoder modem format. */
#define VSS_MEDIA_ID_AMR_WB_MODEM 0x00010FC7
@@ -652,12 +656,17 @@
uint32_t *pkt_len,
void *private_data);
+struct q_min_max_rate {
+ uint32_t min_rate;
+ uint32_t max_rate;
+};
struct mvs_driver_info {
uint32_t media_type;
uint32_t rate;
uint32_t network_type;
uint32_t dtx_mode;
+ struct q_min_max_rate q_min_max_rate;
ul_cb_fn ul_cb;
dl_cb_fn dl_cb;
void *private_data;
@@ -750,7 +759,8 @@
void voice_config_vocoder(uint32_t media_type,
uint32_t rate,
uint32_t network_type,
- uint32_t dtx_mode);
+ uint32_t dtx_mode,
+ struct q_min_max_rate q_min_max_rate);
int voice_start_record(uint32_t rec_mode, uint32_t set);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index 2dae9a8..0b4997c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -38,7 +38,7 @@
struct audio_mvs_buf_node {
struct list_head list;
- struct msm_audio_mvs_frame frame;
+ struct q6_msm_audio_mvs_frame frame;
};
struct audio_mvs_info_type {
@@ -47,6 +47,7 @@
uint32_t mvs_mode;
uint32_t rate_type;
uint32_t dtx_mode;
+ struct q_min_max_rate min_max_rate;
struct list_head in_queue;
struct list_head free_in_queue;
@@ -110,7 +111,8 @@
* Bits 0-3: Frame rate
* Bits 4-7: Frame type
*/
- buf_node->frame.frame_type = ((*voc_pkt) & 0xF0) >> 4;
+ buf_node->frame.header.frame_type =
+ ((*voc_pkt) & 0xF0) >> 4;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -124,7 +126,7 @@
}
case MVS_MODE_IS127: {
- buf_node->frame.frame_type = 0;
+ buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -147,7 +149,7 @@
* Header format:
* Bits 0-1: Frame type
*/
- buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+ 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
@@ -177,7 +179,8 @@
* Header format:
* Bits 0-1: Frame type
*/
- buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+ 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
@@ -213,7 +216,7 @@
* Bits 0-1: Frame type
* Bits 2-3: Frame rate
*/
- buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+ 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
@@ -244,7 +247,8 @@
* Bits 0-1: Frame type
* Bits 2-3: Frame rate
*/
- buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+ 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
@@ -267,8 +271,25 @@
break;
}
+ case MVS_MODE_4GV_NB:
+ case MVS_MODE_4GV_WB: {
+ /* Remove the DSP frame info header.
+ * Header format:
+ * Bits 0-3: frame rate
+ */
+ buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
+ 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;
+ }
+
default: {
- buf_node->frame.frame_type = 0;
+ buf_node->frame.header.frame_type = 0;
buf_node->frame.len = pkt_len;
@@ -314,8 +335,9 @@
* Bits 0-3: Frame rate
* Bits 4-7: Frame type
*/
- *voc_pkt = ((buf_node->frame.frame_type & 0x0F) << 4) |
- (rate_type & 0x0F);
+ *voc_pkt =
+ ((buf_node->frame.header.frame_type & 0x0F) << 4) |
+ (rate_type & 0x0F);
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -333,7 +355,7 @@
* Bits 0-3: Frame rate
* Bits 4-7: Frame type
*/
- *voc_pkt = rate_type & 0x0F;
+ *voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -353,7 +375,7 @@
/* Add the first DSP frame info header. Header format:
* Bits 0-1: Frame type
*/
- *voc_pkt = buf_node->frame.frame_type & 0x03;
+ *voc_pkt = buf_node->frame.header.frame_type & 0x03;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -376,7 +398,8 @@
* Header format:
* Bits 0-1: Frame type
*/
- *voc_pkt = buf_node->frame.frame_type & 0x03;
+ *voc_pkt = buf_node->frame.header.frame_type
+ & 0x03;
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = *pkt_len +
@@ -409,7 +432,7 @@
* Bits 2-3: Frame rate
*/
*voc_pkt = ((rate_type & 0x0F) << 2) |
- (buf_node->frame.frame_type & 0x03);
+ (buf_node->frame.header.frame_type & 0x03);
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -434,7 +457,7 @@
* Bits 2-3: Frame rate
*/
*voc_pkt = ((rate_type & 0x0F) << 2) |
- (buf_node->frame.frame_type & 0x03);
+ (buf_node->frame.header.frame_type & 0x03);
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
*pkt_len = *pkt_len +
@@ -458,6 +481,23 @@
break;
}
+ case MVS_MODE_4GV_NB:
+ case MVS_MODE_4GV_WB: {
+ /* Add the DSP frame info header. Header format:
+ * Bits 0-3 : Frame rate
+ */
+ *voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
+ 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;
@@ -487,6 +527,14 @@
media_type = VSS_MEDIA_ID_EVRC_MODEM;
break;
+ case MVS_MODE_4GV_NB:
+ media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+ break;
+
+ case MVS_MODE_4GV_WB:
+ media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+ break;
+
case MVS_MODE_AMR:
media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
break;
@@ -533,6 +581,7 @@
switch (mvs_mode) {
case MVS_MODE_IS127:
+ case MVS_MODE_4GV_NB:
case MVS_MODE_AMR:
case MVS_MODE_LINEAR_PCM:
case MVS_MODE_PCM:
@@ -541,6 +590,7 @@
network_type = VSS_NETWORK_ID_VOIP_NB;
break;
+ case MVS_MODE_4GV_WB:
case MVS_MODE_AMR_WB:
case MVS_MODE_PCM_WB:
network_type = VSS_NETWORK_ID_VOIP_WB;
@@ -576,7 +626,8 @@
audio_mvs_get_media_type(audio->mvs_mode, audio->rate_type),
audio_mvs_get_rate(audio->mvs_mode, audio->rate_type),
audio_mvs_get_network_type(audio->mvs_mode),
- audio->dtx_mode);
+ audio->dtx_mode,
+ audio->min_max_rate);
audio->state = AUDIO_MVS_STARTED;
} else {
@@ -729,7 +780,7 @@
if ((audio->state == AUDIO_MVS_STARTED) &&
(!list_empty(&audio->out_queue))) {
- if (count >= sizeof(struct msm_audio_mvs_frame)) {
+ if (count >= sizeof(struct q6_msm_audio_mvs_frame)) {
buf_node = list_first_entry(&audio->out_queue,
struct audio_mvs_buf_node,
list);
@@ -737,11 +788,11 @@
rc = copy_to_user(buf,
&buf_node->frame,
- sizeof(struct msm_audio_mvs_frame));
+ sizeof(struct q6_msm_audio_mvs_frame));
if (rc == 0) {
rc = buf_node->frame.len +
- sizeof(buf_node->frame.frame_type) +
+ sizeof(buf_node->frame.header) +
sizeof(buf_node->frame.len);
} else {
pr_err("%s: Copy to user retuned %d",
@@ -755,7 +806,7 @@
} else {
pr_err("%s: Read count %d < sizeof(frame) %d",
__func__, count,
- sizeof(struct msm_audio_mvs_frame));
+ sizeof(struct q6_msm_audio_mvs_frame));
rc = -ENOMEM;
}
@@ -799,7 +850,7 @@
mutex_lock(&audio->in_lock);
if (audio->state == AUDIO_MVS_STARTED) {
- if (count <= sizeof(struct msm_audio_mvs_frame)) {
+ if (count <= sizeof(struct q6_msm_audio_mvs_frame)) {
if (!list_empty(&audio->free_in_queue)) {
buf_node =
list_first_entry(&audio->free_in_queue,
@@ -818,7 +869,7 @@
} else {
pr_err("%s: Write count %d < sizeof(frame) %d",
__func__, count,
- sizeof(struct msm_audio_mvs_frame));
+ sizeof(struct q6_msm_audio_mvs_frame));
rc = -ENOMEM;
}
@@ -863,7 +914,8 @@
config.mvs_mode = audio->mvs_mode;
config.rate_type = audio->rate_type;
config.dtx_mode = audio->dtx_mode;
-
+ config.min_max_rate.min_rate = audio->min_max_rate.min_rate;
+ config.min_max_rate.max_rate = audio->min_max_rate.max_rate;
mutex_unlock(&audio->lock);
rc = copy_to_user((void *)arg, &config, sizeof(config));
@@ -888,6 +940,10 @@
audio->mvs_mode = config.mvs_mode;
audio->rate_type = config.rate_type;
audio->dtx_mode = config.dtx_mode;
+ audio->min_max_rate.min_rate =
+ config.min_max_rate.min_rate;
+ audio->min_max_rate.max_rate =
+ config.min_max_rate.max_rate;
} else {
pr_err("%s: Set confg called in state %d\n",
__func__, audio->state);
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 7472849..1ab615a 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1117,10 +1117,12 @@
/* Set encoder properties. */
switch (common.mvs_info.media_type) {
+ case VSS_MEDIA_ID_4GV_NB_MODEM:
+ case VSS_MEDIA_ID_4GV_WB_MODEM:
case VSS_MEDIA_ID_EVRC_MODEM: {
struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
- pr_info("%s: Setting EVRC min-max rate\n", __func__);
+ pr_info("%s: Setting CDMA min-max rate\n", __func__);
cvs_set_cdma_rate.hdr.hdr_field =
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1133,14 +1135,16 @@
cvs_set_cdma_rate.hdr.token = 0;
cvs_set_cdma_rate.hdr.opcode =
VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
- cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
- cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
+ cvs_set_cdma_rate.cdma_rate.min_rate =
+ common.mvs_info.q_min_max_rate.min_rate;
+ cvs_set_cdma_rate.cdma_rate.max_rate =
+ common.mvs_info.q_min_max_rate.max_rate;
v->cvs_state = CMD_STATUS_FAIL;
ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
if (ret < 0) {
- pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
+ pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
__func__, ret);
goto done;
@@ -1156,6 +1160,10 @@
goto done;
}
+ if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
+ (common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
+ ret = voice_set_dtx(v);
+
break;
}
@@ -2472,12 +2480,14 @@
void voice_config_vocoder(uint32_t media_type,
uint32_t rate,
uint32_t network_type,
- uint32_t dtx_mode)
+ uint32_t dtx_mode,
+ struct q_min_max_rate q_min_max_rate)
{
common.mvs_info.media_type = media_type;
common.mvs_info.rate = rate;
common.mvs_info.network_type = network_type;
common.mvs_info.dtx_mode = dtx_mode;
+ common.mvs_info.q_min_max_rate = q_min_max_rate;
}
static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index 37a6ee7..c934aee 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -94,14 +94,30 @@
MVS_G729A_ERASURE
};
+struct min_max_rate {
+ uint32_t min_rate;
+ uint32_t max_rate;
+};
+
struct msm_audio_mvs_config {
uint32_t mvs_mode;
uint32_t rate_type;
+ struct min_max_rate min_max_rate;
uint32_t dtx_mode;
};
#define MVS_MAX_VOC_PKT_SIZE 640
+struct q6_msm_audio_mvs_frame {
+ union {
+ uint32_t frame_type;
+ uint32_t packet_rate;
+ } header;
+ uint32_t len;
+ uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE];
+
+};
+
struct msm_audio_mvs_frame {
uint32_t frame_type;
uint32_t len;