Loading asoc/msm-pcm-voice-v2.c +18 −0 Original line number Diff line number Diff line Loading @@ -519,6 +519,22 @@ static int msm_voice_rx_device_mute_put(struct snd_kcontrol *kcontrol, return ret; } static int msm_voice_mbd_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ucontrol->value.integer.value[0] = voc_get_mbd_enable(); return 0; } static int msm_voice_mbd_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { bool enable = ucontrol->value.integer.value[0]; voc_set_mbd_enable(enable); return 0; } static const char * const tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; Loading Loading @@ -664,6 +680,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { }, SOC_SINGLE_MULTI_EXT("Voice Sidetone Enable", SND_SOC_NOPM, 0, 1, 0, 1, msm_voice_sidetone_get, msm_voice_sidetone_put), SOC_SINGLE_BOOL_EXT("Voice Mic Break Enable", 0, msm_voice_mbd_get, msm_voice_mbd_put), }; static const struct snd_pcm_ops msm_pcm_ops = { Loading dsp/q6voice.c +211 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v, static int voice_send_mvm_cal_network_cmd(struct voice_data *v); static int voice_send_mvm_media_type_cmd(struct voice_data *v); static int voice_send_mvm_cvd_version_cmd(struct voice_data *v); static int voice_send_mvm_event_class_cmd(struct voice_data *v, uint32_t event_id, uint32_t class_id); static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v); static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v); static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, Loading Loading @@ -767,6 +770,70 @@ static int voice_send_mvm_cvd_version_cmd(struct voice_data *v) return ret; } static int voice_send_mvm_event_class_cmd(struct voice_data *v, uint32_t event_id, uint32_t class_id) { struct vss_inotify_cmd_event_class_t mvm_event; int ret = 0; void *apr_mvm = NULL; u16 mvm_handle = 0; if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; } apr_mvm = common.apr_q6_mvm; if (!apr_mvm) { pr_err("%s: apr_mvm is NULL.\n", __func__); return -EINVAL; } memset(&mvm_event, 0, sizeof(mvm_event)); mvm_handle = voice_get_mvm_handle(v); mvm_event.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); mvm_event.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(mvm_event) - APR_HDR_SIZE); mvm_event.hdr.src_port = voice_get_idx_for_session(v->session_id); mvm_event.hdr.dest_port = mvm_handle; mvm_event.hdr.token = 0; mvm_event.hdr.opcode = event_id; mvm_event.class_id = class_id; v->mvm_state = CMD_STATUS_FAIL; v->async_err = 0; ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_event); if (ret < 0) { pr_err("%s: Error %d sending %x event\n", __func__, ret, event_id); goto fail; } ret = wait_event_timeout(v->mvm_wait, (v->mvm_state == CMD_STATUS_SUCCESS), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout %d\n", __func__, ret); ret = -ETIMEDOUT; goto fail; } if (v->async_err > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str( v->async_err)); ret = adsp_err_get_lnx_err_code( v->async_err); goto fail; } return 0; fail: return ret; } static int voice_send_dual_control_cmd(struct voice_data *v) { int ret = 0; Loading Loading @@ -4243,6 +4310,23 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) return ret; } static void voice_mic_break_work_fn(struct work_struct *work) { int ret = 0; char event[25] = ""; struct voice_data *v = container_of(work, struct voice_data, voice_mic_break_work); snprintf(event, sizeof(event), "MIC_BREAK_STATUS=%s", v->mic_break_status ? "TRUE" : "FALSE"); mutex_lock(&common.common_lock); ret = q6core_send_uevent(common.uevent_data, event); if (ret) pr_err("%s: Send UEvent %s failed :%d\n", __func__, event, ret); mutex_unlock(&common.common_lock); } static int voice_setup_vocproc(struct voice_data *v) { struct module_instance_info mod_inst_info; Loading Loading @@ -4341,6 +4425,11 @@ static int voice_setup_vocproc(struct voice_data *v) if (v->hd_enable) voice_send_hd_cmd(v, v->hd_enable); if (common.mic_break_enable) voice_send_mvm_event_class_cmd(v, VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS, VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); rtac_add_voice(voice_get_cvs_handle(v), voice_get_cvp_handle(v), v->dev_rx.port_id, v->dev_tx.port_id, Loading Loading @@ -5034,6 +5123,11 @@ static int voice_destroy_vocproc(struct voice_data *v) /* Unload topology modules */ voice_unload_topo_modules(); if (common.mic_break_enable) voice_send_mvm_event_class_cmd(v, VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS, VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); /* destrop cvp session */ cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), Loading Loading @@ -6625,6 +6719,70 @@ uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) } EXPORT_SYMBOL(voc_get_route_flag); /** * voc_get_mbd_enable - * Retrieve mic break detection enable state * * Returns true if mic break detection is enabled or false if disabled */ bool voc_get_mbd_enable(void) { bool enable = false; mutex_lock(&common.common_lock); enable = common.mic_break_enable; mutex_unlock(&common.common_lock); return enable; } EXPORT_SYMBOL(voc_get_mbd_enable); /** * voc_set_mbd_enable - * Set mic break detection enable state * * @enable: mic break detection state to set * * Returns 0 */ uint8_t voc_set_mbd_enable(bool enable) { struct voice_data *v = NULL; struct voice_session_itr itr; bool check_and_send_event = false; uint32_t event_id = VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS; uint32_t class_id = VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE; mutex_lock(&common.common_lock); if (common.mic_break_enable != enable) check_and_send_event = true; common.mic_break_enable = enable; mutex_unlock(&common.common_lock); if (!check_and_send_event) return 0; if (!enable) event_id = VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS; memset(&itr, 0, sizeof(itr)); voice_itr_init(&itr, ALL_SESSION_VSID); while (voice_itr_get_next_session(&itr, &v)) { if (v != NULL) { mutex_lock(&v->lock); if (is_voc_state_active(v->voc_state)) { voice_send_mvm_event_class_cmd(v, event_id, class_id); } mutex_unlock(&v->lock); } } return 0; } EXPORT_SYMBOL(voc_set_mbd_enable); /** * voc_end_voice_call - * command to end voice call Loading Loading @@ -7171,6 +7329,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) uint32_t *ptr = NULL; struct common_data *c = NULL; struct voice_data *v = NULL; struct vss_evt_voice_activity *voice_act_update = NULL; int i = 0; struct vss_iversion_rsp_get_t *version_rsp = NULL; Loading Loading @@ -7276,6 +7435,8 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) case VSS_IMVM_CMD_STANDBY_VOICE: case VSS_IHDVOICE_CMD_ENABLE: case VSS_IHDVOICE_CMD_DISABLE: case VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS: case VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS: pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); v->mvm_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; Loading Loading @@ -7380,7 +7541,33 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) v->mvm_state = CMD_STATUS_SUCCESS; wake_up(&v->mvm_wait); } } else if (data->opcode == VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE) { if (data->payload_size == sizeof(struct vss_evt_voice_activity)) { voice_act_update = (struct vss_evt_voice_activity *) data->payload; /* Drop notifications other than Mic Break */ if ((voice_act_update->activity != VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK) && (voice_act_update->activity != VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK)) return 0; switch (voice_act_update->activity) { case VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK: v->mic_break_status = true; break; case VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK: v->mic_break_status = false; break; } if (c->mic_break_enable) schedule_work(&(v->voice_mic_break_work)); } } return 0; } Loading Loading @@ -9642,6 +9829,14 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, return ret; } static void voc_release_uevent_data(struct kobject *kobj) { struct audio_uevent_data *data = container_of(kobj, struct audio_uevent_data, kobj); kfree(data); } /** * is_voc_initialized: * Loading Loading @@ -9694,6 +9889,18 @@ int __init voice_init(void) mutex_init(&common.common_lock); common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL); if (!common.uevent_data) return -ENOMEM; /* * Set release function to cleanup memory related to kobject * before initializing the kobject. */ common.uevent_data->ktype.release = voc_release_uevent_data; q6core_init_uevent_data(common.uevent_data, "q6voice_uevent"); common.mic_break_enable = false; /* Initialize session id with vsid */ init_session_id(); Loading Loading @@ -9734,6 +9941,9 @@ int __init voice_init(void) common.voice[i].voc_state = VOC_INIT; INIT_WORK(&common.voice[i].voice_mic_break_work, voice_mic_break_work_fn); init_waitqueue_head(&common.voice[i].mvm_wait); init_waitqueue_head(&common.voice[i].cvs_wait); init_waitqueue_head(&common.voice[i].cvp_wait); Loading @@ -9754,6 +9964,7 @@ int __init voice_init(void) void voice_exit(void) { q6core_destroy_uevent_data(common.uevent_data); voice_delete_cal_data(); free_cal_map_table(); } include/dsp/q6voice.h +48 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/msm_ion.h> #include <sound/voice_params.h> #include <dsp/rtac.h> #include <dsp/q6core.h> #include <ipc/apr.h> #define MAX_VOC_PKT_SIZE 642 Loading Loading @@ -494,6 +495,19 @@ struct vss_icommon_cmd_set_param { #define VSS_IHDVOICE_CMD_ENABLE 0x000130A2 #define VSS_IHDVOICE_CMD_DISABLE 0x000130A3 /* To listen for events from MVM module */ #define VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS 0x00012E56 /* To cancel listening for events from MVM module */ #define VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS 0x00012E57 /* To receive ongoing voice activity notification */ #define VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE 0x000131EF /* Voice activity notification from MVM */ #define VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE 0x000131F0 /* Mic path is broken. */ #define VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK 0x000131F3 /* Mic path is restored. */ #define VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK 0x000131F4 enum msm_audio_voc_rate { VOC_0_RATE, /* Blank frame */ VOC_8_RATE, /* 1/8 rate */ Loading Loading @@ -719,6 +733,33 @@ struct vss_imemory_cmd_unmap_t { uint32_t mem_handle; } __packed; /* * Payload structure for VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS and * VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS commands. */ struct vss_inotify_cmd_event_class_t { struct apr_hdr hdr; /* Event class ID to listen for. */ uint32_t class_id; } __packed; /* Payload structure for the VSS_ICOMMOM_EVT_VOICE_ACTIVITY_UPDATE event. */ struct vss_evt_voice_activity { uint32_t activity; /* * Specifies the voice acitivity. * @values * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_UNMUTE * #VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK * #VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_UNMUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_UNMUTE */ } __packed; /* TO CVS commands */ #define VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x00011140 /**< Wait for APRV2_IBASIC_RSP_RESULT response. */ Loading Loading @@ -1854,6 +1895,9 @@ struct voice_data { struct incall_music_info music_info; struct voice_rec_route_state rec_route_state; bool mic_break_status; struct work_struct voice_mic_break_work; }; #define MAX_VOC_SESSIONS 8 Loading Loading @@ -1907,6 +1951,8 @@ struct common_data { struct shared_mem_info source_tracking_sh_mem; struct vss_isourcetrack_activity_data_t sourceTrackingResponse; bool sidetone_enable; bool mic_break_enable; struct audio_uevent_data *uevent_data; }; struct voice_session_itr { Loading Loading @@ -1998,6 +2044,8 @@ int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, int voc_get_rx_device_mute(uint32_t session_id); int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); bool voc_get_mbd_enable(void); uint8_t voc_set_mbd_enable(bool enable); int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); void voc_disable_dtmf_det_on_active_sessions(void); int voc_alloc_cal_shared_memory(void); Loading Loading
asoc/msm-pcm-voice-v2.c +18 −0 Original line number Diff line number Diff line Loading @@ -519,6 +519,22 @@ static int msm_voice_rx_device_mute_put(struct snd_kcontrol *kcontrol, return ret; } static int msm_voice_mbd_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { ucontrol->value.integer.value[0] = voc_get_mbd_enable(); return 0; } static int msm_voice_mbd_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { bool enable = ucontrol->value.integer.value[0]; voc_set_mbd_enable(enable); return 0; } static const char * const tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; Loading Loading @@ -664,6 +680,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { }, SOC_SINGLE_MULTI_EXT("Voice Sidetone Enable", SND_SOC_NOPM, 0, 1, 0, 1, msm_voice_sidetone_get, msm_voice_sidetone_put), SOC_SINGLE_BOOL_EXT("Voice Mic Break Enable", 0, msm_voice_mbd_get, msm_voice_mbd_put), }; static const struct snd_pcm_ops msm_pcm_ops = { Loading
dsp/q6voice.c +211 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v, static int voice_send_mvm_cal_network_cmd(struct voice_data *v); static int voice_send_mvm_media_type_cmd(struct voice_data *v); static int voice_send_mvm_cvd_version_cmd(struct voice_data *v); static int voice_send_mvm_event_class_cmd(struct voice_data *v, uint32_t event_id, uint32_t class_id); static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v); static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v); static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, Loading Loading @@ -767,6 +770,70 @@ static int voice_send_mvm_cvd_version_cmd(struct voice_data *v) return ret; } static int voice_send_mvm_event_class_cmd(struct voice_data *v, uint32_t event_id, uint32_t class_id) { struct vss_inotify_cmd_event_class_t mvm_event; int ret = 0; void *apr_mvm = NULL; u16 mvm_handle = 0; if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; } apr_mvm = common.apr_q6_mvm; if (!apr_mvm) { pr_err("%s: apr_mvm is NULL.\n", __func__); return -EINVAL; } memset(&mvm_event, 0, sizeof(mvm_event)); mvm_handle = voice_get_mvm_handle(v); mvm_event.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); mvm_event.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(mvm_event) - APR_HDR_SIZE); mvm_event.hdr.src_port = voice_get_idx_for_session(v->session_id); mvm_event.hdr.dest_port = mvm_handle; mvm_event.hdr.token = 0; mvm_event.hdr.opcode = event_id; mvm_event.class_id = class_id; v->mvm_state = CMD_STATUS_FAIL; v->async_err = 0; ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_event); if (ret < 0) { pr_err("%s: Error %d sending %x event\n", __func__, ret, event_id); goto fail; } ret = wait_event_timeout(v->mvm_wait, (v->mvm_state == CMD_STATUS_SUCCESS), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event timeout %d\n", __func__, ret); ret = -ETIMEDOUT; goto fail; } if (v->async_err > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str( v->async_err)); ret = adsp_err_get_lnx_err_code( v->async_err); goto fail; } return 0; fail: return ret; } static int voice_send_dual_control_cmd(struct voice_data *v) { int ret = 0; Loading Loading @@ -4243,6 +4310,23 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) return ret; } static void voice_mic_break_work_fn(struct work_struct *work) { int ret = 0; char event[25] = ""; struct voice_data *v = container_of(work, struct voice_data, voice_mic_break_work); snprintf(event, sizeof(event), "MIC_BREAK_STATUS=%s", v->mic_break_status ? "TRUE" : "FALSE"); mutex_lock(&common.common_lock); ret = q6core_send_uevent(common.uevent_data, event); if (ret) pr_err("%s: Send UEvent %s failed :%d\n", __func__, event, ret); mutex_unlock(&common.common_lock); } static int voice_setup_vocproc(struct voice_data *v) { struct module_instance_info mod_inst_info; Loading Loading @@ -4341,6 +4425,11 @@ static int voice_setup_vocproc(struct voice_data *v) if (v->hd_enable) voice_send_hd_cmd(v, v->hd_enable); if (common.mic_break_enable) voice_send_mvm_event_class_cmd(v, VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS, VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); rtac_add_voice(voice_get_cvs_handle(v), voice_get_cvp_handle(v), v->dev_rx.port_id, v->dev_tx.port_id, Loading Loading @@ -5034,6 +5123,11 @@ static int voice_destroy_vocproc(struct voice_data *v) /* Unload topology modules */ voice_unload_topo_modules(); if (common.mic_break_enable) voice_send_mvm_event_class_cmd(v, VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS, VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); /* destrop cvp session */ cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), Loading Loading @@ -6625,6 +6719,70 @@ uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) } EXPORT_SYMBOL(voc_get_route_flag); /** * voc_get_mbd_enable - * Retrieve mic break detection enable state * * Returns true if mic break detection is enabled or false if disabled */ bool voc_get_mbd_enable(void) { bool enable = false; mutex_lock(&common.common_lock); enable = common.mic_break_enable; mutex_unlock(&common.common_lock); return enable; } EXPORT_SYMBOL(voc_get_mbd_enable); /** * voc_set_mbd_enable - * Set mic break detection enable state * * @enable: mic break detection state to set * * Returns 0 */ uint8_t voc_set_mbd_enable(bool enable) { struct voice_data *v = NULL; struct voice_session_itr itr; bool check_and_send_event = false; uint32_t event_id = VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS; uint32_t class_id = VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE; mutex_lock(&common.common_lock); if (common.mic_break_enable != enable) check_and_send_event = true; common.mic_break_enable = enable; mutex_unlock(&common.common_lock); if (!check_and_send_event) return 0; if (!enable) event_id = VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS; memset(&itr, 0, sizeof(itr)); voice_itr_init(&itr, ALL_SESSION_VSID); while (voice_itr_get_next_session(&itr, &v)) { if (v != NULL) { mutex_lock(&v->lock); if (is_voc_state_active(v->voc_state)) { voice_send_mvm_event_class_cmd(v, event_id, class_id); } mutex_unlock(&v->lock); } } return 0; } EXPORT_SYMBOL(voc_set_mbd_enable); /** * voc_end_voice_call - * command to end voice call Loading Loading @@ -7171,6 +7329,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) uint32_t *ptr = NULL; struct common_data *c = NULL; struct voice_data *v = NULL; struct vss_evt_voice_activity *voice_act_update = NULL; int i = 0; struct vss_iversion_rsp_get_t *version_rsp = NULL; Loading Loading @@ -7276,6 +7435,8 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) case VSS_IMVM_CMD_STANDBY_VOICE: case VSS_IHDVOICE_CMD_ENABLE: case VSS_IHDVOICE_CMD_DISABLE: case VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS: case VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS: pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); v->mvm_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; Loading Loading @@ -7380,7 +7541,33 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) v->mvm_state = CMD_STATUS_SUCCESS; wake_up(&v->mvm_wait); } } else if (data->opcode == VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE) { if (data->payload_size == sizeof(struct vss_evt_voice_activity)) { voice_act_update = (struct vss_evt_voice_activity *) data->payload; /* Drop notifications other than Mic Break */ if ((voice_act_update->activity != VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK) && (voice_act_update->activity != VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK)) return 0; switch (voice_act_update->activity) { case VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK: v->mic_break_status = true; break; case VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK: v->mic_break_status = false; break; } if (c->mic_break_enable) schedule_work(&(v->voice_mic_break_work)); } } return 0; } Loading Loading @@ -9642,6 +9829,14 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, return ret; } static void voc_release_uevent_data(struct kobject *kobj) { struct audio_uevent_data *data = container_of(kobj, struct audio_uevent_data, kobj); kfree(data); } /** * is_voc_initialized: * Loading Loading @@ -9694,6 +9889,18 @@ int __init voice_init(void) mutex_init(&common.common_lock); common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL); if (!common.uevent_data) return -ENOMEM; /* * Set release function to cleanup memory related to kobject * before initializing the kobject. */ common.uevent_data->ktype.release = voc_release_uevent_data; q6core_init_uevent_data(common.uevent_data, "q6voice_uevent"); common.mic_break_enable = false; /* Initialize session id with vsid */ init_session_id(); Loading Loading @@ -9734,6 +9941,9 @@ int __init voice_init(void) common.voice[i].voc_state = VOC_INIT; INIT_WORK(&common.voice[i].voice_mic_break_work, voice_mic_break_work_fn); init_waitqueue_head(&common.voice[i].mvm_wait); init_waitqueue_head(&common.voice[i].cvs_wait); init_waitqueue_head(&common.voice[i].cvp_wait); Loading @@ -9754,6 +9964,7 @@ int __init voice_init(void) void voice_exit(void) { q6core_destroy_uevent_data(common.uevent_data); voice_delete_cal_data(); free_cal_map_table(); }
include/dsp/q6voice.h +48 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/msm_ion.h> #include <sound/voice_params.h> #include <dsp/rtac.h> #include <dsp/q6core.h> #include <ipc/apr.h> #define MAX_VOC_PKT_SIZE 642 Loading Loading @@ -494,6 +495,19 @@ struct vss_icommon_cmd_set_param { #define VSS_IHDVOICE_CMD_ENABLE 0x000130A2 #define VSS_IHDVOICE_CMD_DISABLE 0x000130A3 /* To listen for events from MVM module */ #define VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS 0x00012E56 /* To cancel listening for events from MVM module */ #define VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS 0x00012E57 /* To receive ongoing voice activity notification */ #define VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE 0x000131EF /* Voice activity notification from MVM */ #define VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE 0x000131F0 /* Mic path is broken. */ #define VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK 0x000131F3 /* Mic path is restored. */ #define VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK 0x000131F4 enum msm_audio_voc_rate { VOC_0_RATE, /* Blank frame */ VOC_8_RATE, /* 1/8 rate */ Loading Loading @@ -719,6 +733,33 @@ struct vss_imemory_cmd_unmap_t { uint32_t mem_handle; } __packed; /* * Payload structure for VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS and * VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS commands. */ struct vss_inotify_cmd_event_class_t { struct apr_hdr hdr; /* Event class ID to listen for. */ uint32_t class_id; } __packed; /* Payload structure for the VSS_ICOMMOM_EVT_VOICE_ACTIVITY_UPDATE event. */ struct vss_evt_voice_activity { uint32_t activity; /* * Specifies the voice acitivity. * @values * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_UNMUTE * #VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK * #VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_UNMUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_MUTE * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_UNMUTE */ } __packed; /* TO CVS commands */ #define VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x00011140 /**< Wait for APRV2_IBASIC_RSP_RESULT response. */ Loading Loading @@ -1854,6 +1895,9 @@ struct voice_data { struct incall_music_info music_info; struct voice_rec_route_state rec_route_state; bool mic_break_status; struct work_struct voice_mic_break_work; }; #define MAX_VOC_SESSIONS 8 Loading Loading @@ -1907,6 +1951,8 @@ struct common_data { struct shared_mem_info source_tracking_sh_mem; struct vss_isourcetrack_activity_data_t sourceTrackingResponse; bool sidetone_enable; bool mic_break_enable; struct audio_uevent_data *uevent_data; }; struct voice_session_itr { Loading Loading @@ -1998,6 +2044,8 @@ int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, int voc_get_rx_device_mute(uint32_t session_id); int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); bool voc_get_mbd_enable(void); uint8_t voc_set_mbd_enable(bool enable); int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); void voc_disable_dtmf_det_on_active_sessions(void); int voc_alloc_cal_shared_memory(void); Loading