1 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
13 #include <linux/init.h>
14 #include <linux/err.h>
15 #include <linux/module.h>
16 #include <linux/time.h>
17 #include <linux/wait.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #include <linux/dma-mapping.h>
21 #include <sound/core.h>
22 #include <sound/soc.h>
23 #include <sound/soc-dapm.h>
24 #include <sound/pcm.h>
25 #include <sound/initval.h>
26 #include <sound/control.h>
28 #include <linux/of_device.h>
30 #include "msm-pcm-voice-v2.h"
31 #include "msm-qti-pp-config.h"
34 struct msm_dtmf_detected_event_data {
37 struct vss_istream_evt_rx_dtmf_detected dtmf_payload;
40 static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX];
42 static struct snd_pcm_hardware msm_pcm_hardware = {
44 .info = (SNDRV_PCM_INFO_INTERLEAVED |
45 SNDRV_PCM_INFO_PAUSE |
46 SNDRV_PCM_INFO_RESUME),
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
54 .buffer_bytes_max = 4096 * 2,
55 .period_bytes_min = 2048,
56 .period_bytes_max = 4096,
63 static int is_valid_session_id(uint32_t session_id)
68 case VOICE_SESSION_VSID:
69 case VOICE2_SESSION_VSID:
70 case VOLTE_SESSION_VSID:
71 case QCHAT_SESSION_VSID:
72 case VOWLAN_SESSION_VSID:
73 case VOICEMMODE1_VSID:
74 case VOICEMMODE2_VSID:
75 case ALL_SESSION_VSID:
79 pr_debug("%s: Invalid session_id : %x\n", __func__, session_id);
85 static int get_idx_for_session(uint32_t session_id)
90 case VOICE_SESSION_VSID:
91 idx = VOICE_SESSION_INDEX;
93 case VOICE2_SESSION_VSID:
94 idx = VOICE2_SESSION_INDEX;
96 case VOLTE_SESSION_VSID:
97 idx = VOLTE_SESSION_INDEX;
99 case QCHAT_SESSION_VSID:
100 idx = QCHAT_SESSION_INDEX;
102 case VOWLAN_SESSION_VSID:
103 idx = VOWLAN_SESSION_INDEX;
105 case VOICEMMODE1_VSID:
106 idx = VOICEMMODE1_INDEX;
108 case VOICEMMODE2_VSID:
109 idx = VOICEMMODE2_INDEX;
111 case ALL_SESSION_VSID:
112 idx = VOICE_SESSION_INDEX_MAX - 1;
115 pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
122 static bool is_volte(struct msm_voice *pvolte)
124 if (pvolte == &voice_info[VOLTE_SESSION_INDEX])
130 static bool is_voice2(struct msm_voice *pvoice2)
132 if (pvoice2 == &voice_info[VOICE2_SESSION_INDEX])
138 static bool is_qchat(struct msm_voice *pqchat)
140 if (pqchat == &voice_info[QCHAT_SESSION_INDEX])
146 static bool is_vowlan(struct msm_voice *pvowlan)
148 if (pvowlan == &voice_info[VOWLAN_SESSION_INDEX])
154 static bool is_voicemmode1(struct msm_voice *pvoicemmode1)
156 if (pvoicemmode1 == &voice_info[VOICEMMODE1_INDEX])
162 static bool is_voicemmode2(struct msm_voice *pvoicemmode2)
164 if (pvoicemmode2 == &voice_info[VOICEMMODE2_INDEX])
170 static uint32_t get_session_id(struct msm_voice *pvoc)
172 uint32_t session_id = 0;
175 session_id = voc_get_session_id(VOLTE_SESSION_NAME);
176 else if (is_voice2(pvoc))
177 session_id = voc_get_session_id(VOICE2_SESSION_NAME);
178 else if (is_qchat(pvoc))
179 session_id = voc_get_session_id(QCHAT_SESSION_NAME);
180 else if (is_vowlan(pvoc))
181 session_id = voc_get_session_id(VOWLAN_SESSION_NAME);
182 else if (is_voicemmode1(pvoc))
183 session_id = voc_get_session_id(VOICEMMODE1_NAME);
184 else if (is_voicemmode2(pvoc))
185 session_id = voc_get_session_id(VOICEMMODE2_NAME);
187 session_id = voc_get_session_id(VOICE_SESSION_NAME);
192 static void dtmf_rx_detected_evt_hdlr(uint8_t *pkt,
197 struct snd_soc_pcm_runtime *soc_prtd = private_data;
198 struct msm_dtmf_detected_event_data event_data = {ADSP_STREAM_PP_EVENT,
199 sizeof(struct vss_istream_evt_rx_dtmf_detected),
203 pr_err("%s: packet is NULL\n",
209 pr_err("%s: private_data is NULL\n",
214 memcpy(&event_data.dtmf_payload, pkt,
215 sizeof(struct vss_istream_evt_rx_dtmf_detected));
217 ret = msm_adsp_inform_mixer_ctl(soc_prtd, (uint32_t *)&event_data);
219 pr_err("%s: failed to inform mixer ctl. err = %d\n",
225 static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
227 struct snd_pcm_runtime *runtime = substream->runtime;
228 struct msm_voice *prtd = runtime->private_data;
230 pr_debug("%s\n", __func__);
232 if (!prtd->playback_start)
233 prtd->playback_start = 1;
238 static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
240 struct snd_pcm_runtime *runtime = substream->runtime;
241 struct msm_voice *prtd = runtime->private_data;
243 pr_debug("%s\n", __func__);
245 if (!prtd->capture_start)
246 prtd->capture_start = 1;
250 static int msm_pcm_open(struct snd_pcm_substream *substream)
252 struct snd_pcm_runtime *runtime = substream->runtime;
253 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
254 struct msm_voice *voice;
256 if (!strncmp("VoLTE", substream->pcm->id, 5)) {
257 voice = &voice_info[VOLTE_SESSION_INDEX];
258 pr_debug("%s: Open VoLTE Substream Id=%s\n",
259 __func__, substream->pcm->id);
260 } else if (!strncmp("Voice2", substream->pcm->id, 6)) {
261 voice = &voice_info[VOICE2_SESSION_INDEX];
262 pr_debug("%s: Open Voice2 Substream Id=%s\n",
263 __func__, substream->pcm->id);
264 } else if (!strncmp("QCHAT", substream->pcm->id, 5)) {
265 voice = &voice_info[QCHAT_SESSION_INDEX];
266 pr_debug("%s: Open QCHAT Substream Id=%s\n",
267 __func__, substream->pcm->id);
268 } else if (!strncmp("VoWLAN", substream->pcm->id, 6)) {
269 voice = &voice_info[VOWLAN_SESSION_INDEX];
270 pr_debug("%s: Open VoWLAN Substream Id=%s\n",
271 __func__, substream->pcm->id);
272 } else if (!strncmp("VoiceMMode1", substream->pcm->id, 11)) {
273 voice = &voice_info[VOICEMMODE1_INDEX];
274 pr_debug("%s: Open VoiceMMode1 Substream Id=%s\n",
275 __func__, substream->pcm->id);
276 } else if (!strncmp("VoiceMMode2", substream->pcm->id, 11)) {
277 voice = &voice_info[VOICEMMODE2_INDEX];
278 pr_debug("%s: Open VoiceMMode2 Substream Id=%s\n",
279 __func__, substream->pcm->id);
281 voice = &voice_info[VOICE_SESSION_INDEX];
282 pr_debug("%s: Open VOICE Substream Id=%s\n",
283 __func__, substream->pcm->id);
285 mutex_lock(&voice->lock);
287 runtime->hw = msm_pcm_hardware;
289 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
290 voice->playback_substream = substream;
291 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
292 voice->capture_substream = substream;
295 pr_debug("%s: Instance = %d, Stream ID = %s\n",
296 __func__ , voice->instance, substream->pcm->id);
297 runtime->private_data = voice;
299 mutex_unlock(&voice->lock);
300 msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd);
303 static int msm_pcm_playback_close(struct snd_pcm_substream *substream)
305 struct snd_pcm_runtime *runtime = substream->runtime;
306 struct msm_voice *prtd = runtime->private_data;
308 pr_debug("%s\n", __func__);
310 if (prtd->playback_start)
311 prtd->playback_start = 0;
313 prtd->playback_substream = NULL;
317 static int msm_pcm_capture_close(struct snd_pcm_substream *substream)
319 struct snd_pcm_runtime *runtime = substream->runtime;
320 struct msm_voice *prtd = runtime->private_data;
322 pr_debug("%s\n", __func__);
324 if (prtd->capture_start)
325 prtd->capture_start = 0;
326 prtd->capture_substream = NULL;
330 static int msm_pcm_close(struct snd_pcm_substream *substream)
333 struct snd_pcm_runtime *runtime = substream->runtime;
334 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
335 struct msm_voice *prtd = runtime->private_data;
336 uint32_t session_id = 0;
339 mutex_lock(&prtd->lock);
340 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
341 ret = msm_pcm_playback_close(substream);
342 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
343 ret = msm_pcm_capture_close(substream);
346 if (!prtd->playback_start && !prtd->capture_start) {
347 pr_debug("end voice call\n");
349 session_id = get_session_id(prtd);
351 voc_end_voice_call(session_id);
353 mutex_unlock(&prtd->lock);
354 msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd);
358 static int msm_pcm_prepare(struct snd_pcm_substream *substream)
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 struct msm_voice *prtd = runtime->private_data;
363 uint32_t session_id = 0;
365 mutex_lock(&prtd->lock);
367 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
368 ret = msm_pcm_playback_prepare(substream);
369 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
370 ret = msm_pcm_capture_prepare(substream);
372 if (prtd->playback_start && prtd->capture_start) {
373 session_id = get_session_id(prtd);
375 voc_start_voice_call(session_id);
377 mutex_unlock(&prtd->lock);
382 static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
383 struct snd_pcm_hw_params *params)
386 pr_debug("%s: Voice\n", __func__);
388 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
393 static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
396 struct snd_pcm_runtime *runtime = substream->runtime;
397 struct msm_voice *prtd = runtime->private_data;
398 uint32_t session_id = 0;
400 pr_debug("%s: cmd = %d\n", __func__, cmd);
402 session_id = get_session_id(prtd);
405 case SNDRV_PCM_TRIGGER_START:
406 case SNDRV_PCM_TRIGGER_STOP:
407 pr_debug("Start & Stop Voice call not handled in Trigger.\n");
409 case SNDRV_PCM_TRIGGER_RESUME:
410 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
411 pr_debug("%s: resume call session_id = %d\n", __func__,
413 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
414 ret = msm_pcm_playback_prepare(substream);
415 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
416 ret = msm_pcm_capture_prepare(substream);
417 if (prtd->playback_start && prtd->capture_start) {
419 voc_resume_voice_call(session_id);
422 case SNDRV_PCM_TRIGGER_SUSPEND:
423 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
424 pr_debug("%s: pause call session_id=%d\n",
425 __func__, session_id);
426 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
427 if (prtd->playback_start)
428 prtd->playback_start = 0;
429 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
430 if (prtd->capture_start)
431 prtd->capture_start = 0;
434 voc_standby_voice_call(session_id);
443 static int msm_pcm_ioctl(struct snd_pcm_substream *substream,
444 unsigned int cmd, void *arg)
446 struct snd_pcm_runtime *runtime = substream->runtime;
447 struct msm_voice *prtd = runtime->private_data;
448 uint32_t session_id = get_session_id(prtd);
449 enum voice_lch_mode lch_mode;
453 case SNDRV_VOICE_IOCTL_LCH:
454 if (copy_from_user(&lch_mode, (void *)arg,
455 sizeof(enum voice_lch_mode))) {
456 pr_err("%s: Copy from user failed, size %zd\n",
457 __func__, sizeof(enum voice_lch_mode));
463 pr_debug("%s: %s lch_mode:%d\n",
464 __func__, substream->pcm->id, lch_mode);
467 case VOICE_LCH_START:
469 ret = voc_set_lch(session_id, lch_mode);
473 pr_err("%s: Invalid LCH MODE %d\n", __func__, lch_mode);
480 pr_debug("%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
483 ret = snd_pcm_lib_ioctl(substream, cmd, arg);
488 pr_debug("%s: ret %d\n", __func__, ret);
490 pr_err("%s: cmd 0x%x failed %d\n", __func__, cmd, ret);
495 static int msm_voice_sidetone_put(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
499 int sidetone_enable = ucontrol->value.integer.value[0];
500 uint32_t session_id = ALL_SESSION_VSID;
502 if (sidetone_enable < 0) {
503 pr_err("%s: Invalid arguments sidetone enable %d\n",
504 __func__, sidetone_enable);
508 ret = voc_set_afe_sidetone(session_id, sidetone_enable);
509 pr_debug("%s: AFE Sidetone enable=%d session_id=0x%x ret=%d\n",
510 __func__, sidetone_enable, session_id, ret);
514 static int msm_voice_sidetone_get(struct snd_kcontrol *kcontrol,
515 struct snd_ctl_elem_value *ucontrol)
518 ucontrol->value.integer.value[0] = voc_get_afe_sidetone();
522 static int msm_voice_gain_put(struct snd_kcontrol *kcontrol,
523 struct snd_ctl_elem_value *ucontrol)
526 int volume = ucontrol->value.integer.value[0];
527 uint32_t session_id = ucontrol->value.integer.value[1];
528 int ramp_duration = ucontrol->value.integer.value[2];
530 if ((volume < 0) || (ramp_duration < 0)
531 || (ramp_duration > MAX_RAMP_DURATION)) {
532 pr_err(" %s Invalid arguments", __func__);
538 pr_debug("%s: volume: %d session_id: %#x ramp_duration: %d\n", __func__,
539 volume, session_id, ramp_duration);
541 voc_set_rx_vol_step(session_id, RX_PATH, volume, ramp_duration);
547 static int msm_voice_mute_put(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
551 int mute = ucontrol->value.integer.value[0];
552 uint32_t session_id = ucontrol->value.integer.value[1];
553 int ramp_duration = ucontrol->value.integer.value[2];
555 if ((mute < 0) || (mute > 1) || (ramp_duration < 0)
556 || (ramp_duration > MAX_RAMP_DURATION)) {
557 pr_err(" %s Invalid arguments", __func__);
563 pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__,
564 mute, session_id, ramp_duration);
566 ret = voc_set_tx_mute(session_id, TX_PATH, mute, ramp_duration);
572 static int msm_voice_tx_device_mute_put(struct snd_kcontrol *kcontrol,
573 struct snd_ctl_elem_value *ucontrol)
576 int mute = ucontrol->value.integer.value[0];
577 uint32_t session_id = ucontrol->value.integer.value[1];
578 int ramp_duration = ucontrol->value.integer.value[2];
580 if ((mute < 0) || (mute > 1) || (ramp_duration < 0) ||
581 (ramp_duration > MAX_RAMP_DURATION)) {
582 pr_err(" %s Invalid arguments", __func__);
588 pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__,
589 mute, session_id, ramp_duration);
591 ret = voc_set_device_mute(session_id, VSS_IVOLUME_DIRECTION_TX,
592 mute, ramp_duration);
598 static int msm_voice_rx_device_mute_put(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
602 int mute = ucontrol->value.integer.value[0];
603 uint32_t session_id = ucontrol->value.integer.value[1];
604 int ramp_duration = ucontrol->value.integer.value[2];
606 if ((mute < 0) || (mute > 1) || (ramp_duration < 0) ||
607 (ramp_duration > MAX_RAMP_DURATION)) {
608 pr_err(" %s Invalid arguments", __func__);
614 pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__,
615 mute, session_id, ramp_duration);
617 voc_set_device_mute(session_id, VSS_IVOLUME_DIRECTION_RX,
618 mute, ramp_duration);
626 static const char const *tty_mode[] = {"OFF", "HCO", "VCO", "FULL"};
627 static const struct soc_enum msm_tty_mode_enum[] = {
628 SOC_ENUM_SINGLE_EXT(4, tty_mode),
631 static int msm_voice_tty_mode_get(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
634 ucontrol->value.integer.value[0] =
635 voc_get_tty_mode(voc_get_session_id(VOICE_SESSION_NAME));
639 static int msm_voice_tty_mode_put(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
642 int tty_mode = ucontrol->value.integer.value[0];
644 pr_debug("%s: tty_mode=%d\n", __func__, tty_mode);
646 voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode);
647 voc_set_tty_mode(voc_get_session_id(VOICE2_SESSION_NAME), tty_mode);
648 voc_set_tty_mode(voc_get_session_id(VOLTE_SESSION_NAME), tty_mode);
649 voc_set_tty_mode(voc_get_session_id(VOWLAN_SESSION_NAME), tty_mode);
650 voc_set_tty_mode(voc_get_session_id(VOICEMMODE1_NAME), tty_mode);
651 voc_set_tty_mode(voc_get_session_id(VOICEMMODE2_NAME), tty_mode);
656 static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol,
657 struct snd_ctl_elem_value *ucontrol)
659 int st_enable = ucontrol->value.integer.value[0];
660 uint32_t session_id = ucontrol->value.integer.value[1];
661 struct module_instance_info mod_inst_info = {0};
663 pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable,
666 mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST;
667 mod_inst_info.instance_id = INSTANCE_ID_0;
668 voc_set_pp_enable(session_id, mod_inst_info, st_enable);
673 static int msm_voice_hd_voice_put(struct snd_kcontrol *kcontrol,
674 struct snd_ctl_elem_value *ucontrol)
677 uint32_t hd_enable = ucontrol->value.integer.value[0];
678 uint32_t session_id = ucontrol->value.integer.value[1];
680 pr_debug("%s: HD Voice enable=%d session_id=%#x\n", __func__, hd_enable,
683 ret = voc_set_hd_enable(session_id, hd_enable);
688 static int msm_dtmf_detect_rx_vsid_put(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
691 uint32_t session_id = ucontrol->value.integer.value[0];
692 uint32_t enable = ucontrol->value.integer.value[1];
697 pr_debug("%s: sess_id=%d enable=%d\n", __func__, session_id, enable);
699 return voc_enable_dtmf_rx_detection(session_id, enable);
702 static int msm_dtmf_detect_rx_vsid_cb_put(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_value *ucontrol)
705 struct msm_voice *dtmf_voice_info = NULL;
706 uint32_t session_id = ucontrol->value.integer.value[0];
707 uint32_t enable = ucontrol->value.integer.value[1];
709 if (!is_valid_session_id(session_id)) {
710 pr_err(" %s Invalid session_id : %x\n", __func__, session_id);
717 pr_debug("%s: enable dtmf detect cb =%d for session_id=%d\n",
718 __func__, enable, session_id);
720 dtmf_voice_info = &voice_info[get_idx_for_session(session_id)];
721 voc_register_dtmf_rx_detection_cb
722 ((dtmf_rx_det_cb_fn) dtmf_rx_detected_evt_hdlr,
723 (void *) dtmf_voice_info->capture_substream->private_data);
728 static int msm_voice_topology_disable_put(struct snd_kcontrol *kcontrol,
729 struct snd_ctl_elem_value *ucontrol)
732 int disable = ucontrol->value.integer.value[0];
733 uint32_t session_id = ucontrol->value.integer.value[1];
735 if ((disable < 0) || (disable > 1)) {
736 pr_err(" %s Invalid arguments: %d\n", __func__, disable);
741 pr_debug("%s: disable = %d, session_id = %d\n", __func__, disable,
744 ret = voc_disable_topology(session_id, disable);
750 static int msm_voice_cvd_version_info(struct snd_kcontrol *kcontrol,
751 struct snd_ctl_elem_info *uinfo)
755 pr_debug("%s:\n", __func__);
757 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
758 uinfo->count = CVD_VERSION_STRING_MAX_SIZE;
763 static int msm_voice_cvd_version_get(struct snd_kcontrol *kcontrol,
764 struct snd_ctl_elem_value *ucontrol)
766 char cvd_version[CVD_VERSION_STRING_MAX_SIZE] = CVD_VERSION_DEFAULT;
769 pr_debug("%s:\n", __func__);
771 ret = voc_get_cvd_version(cvd_version);
774 pr_err("%s: Error retrieving CVD version, error:%d\n",
777 memcpy(ucontrol->value.bytes.data, cvd_version, sizeof(cvd_version));
782 static struct snd_kcontrol_new msm_voice_controls[] = {
783 SOC_SINGLE_MULTI_EXT("Voice Rx Device Mute", SND_SOC_NOPM, 0, VSID_MAX,
784 0, 3, NULL, msm_voice_rx_device_mute_put),
785 SOC_SINGLE_MULTI_EXT("Voice Tx Device Mute", SND_SOC_NOPM, 0, VSID_MAX,
786 0, 3, NULL, msm_voice_tx_device_mute_put),
787 SOC_SINGLE_MULTI_EXT("Voice Tx Mute", SND_SOC_NOPM, 0, VSID_MAX,
788 0, 3, NULL, msm_voice_mute_put),
789 SOC_SINGLE_MULTI_EXT("Voice Rx Gain", SND_SOC_NOPM, 0, VSID_MAX, 0, 3,
790 NULL, msm_voice_gain_put),
791 SOC_ENUM_EXT("TTY Mode", msm_tty_mode_enum[0], msm_voice_tty_mode_get,
792 msm_voice_tty_mode_put),
793 SOC_SINGLE_MULTI_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2,
794 NULL, msm_voice_slowtalk_put),
795 SOC_SINGLE_MULTI_EXT("Voice Topology Disable", SND_SOC_NOPM, 0,
796 VSID_MAX, 0, 2, NULL,
797 msm_voice_topology_disable_put),
798 SOC_SINGLE_MULTI_EXT("HD Voice Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2,
799 NULL, msm_voice_hd_voice_put),
800 SOC_SINGLE_MULTI_EXT("DTMF_Detect Rx VSID enable",
801 SND_SOC_NOPM, 0, VSID_MAX, 0, 2,
802 NULL, msm_dtmf_detect_rx_vsid_put),
803 SOC_SINGLE_MULTI_EXT("DTMF_Detect Rx Callback VSID enable",
804 SND_SOC_NOPM, 0, VSID_MAX, 0, 2,
805 NULL, msm_dtmf_detect_rx_vsid_cb_put),
807 .access = SNDRV_CTL_ELEM_ACCESS_READ,
808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
809 .name = "CVD Version",
810 .info = msm_voice_cvd_version_info,
811 .get = msm_voice_cvd_version_get,
813 SOC_SINGLE_MULTI_EXT("Voice Sidetone Enable", SND_SOC_NOPM, 0, 1, 0, 1,
814 msm_voice_sidetone_get, msm_voice_sidetone_put),
818 static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
819 struct snd_ctl_elem_value *ucontrol)
824 static int msm_pcm_add_voice_adsp_stream_cmd_control(
825 struct snd_soc_pcm_runtime *rtd)
827 const char *mixer_ctl_name = DSP_STREAM_CMD;
828 const char *deviceNo = "NN";
829 char *mixer_str = NULL;
830 int ctl_len = 0, ret = 0;
831 struct snd_kcontrol_new fe_voice_adsp_stream_cmd_config_control[1] = {
833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
836 .info = msm_adsp_stream_cmd_info,
837 .put = msm_pcm_adsp_stream_cmd_put,
843 pr_err("%s rtd is NULL\n", __func__);
847 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
848 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
852 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
853 fe_voice_adsp_stream_cmd_config_control[0].name = mixer_str;
854 fe_voice_adsp_stream_cmd_config_control[0].private_value =
855 rtd->dai_link->be_id;
856 pr_debug("Registering new mixer ctl %s\n", mixer_str);
857 ret = snd_soc_add_platform_controls(rtd->platform,
858 fe_voice_adsp_stream_cmd_config_control,
859 ARRAY_SIZE(fe_voice_adsp_stream_cmd_config_control));
861 pr_err("%s: failed add ctl %s. err = %d\n",
862 __func__, mixer_str, ret);
868 static int msm_pcm_add_voice_adsp_stream_callback_control(
869 struct snd_soc_pcm_runtime *rtd)
871 const char *mixer_ctl_name = DSP_STREAM_CALLBACK;
872 const char *deviceNo = "NN";
873 char *mixer_str = NULL;
874 int ctl_len = 0, ret = 0;
875 struct snd_kcontrol *kctl;
877 struct snd_kcontrol_new fe_voice_adsp_callback_config_control[1] = {
879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
881 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
882 .info = msm_adsp_stream_callback_info,
883 .get = msm_adsp_stream_callback_get,
889 pr_err("%s NULL rtd\n", __func__);
893 pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n",
894 __func__, rtd->dai_link->name, rtd->dai_link->be_id,
895 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
896 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
897 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
901 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
902 fe_voice_adsp_callback_config_control[0].name = mixer_str;
903 fe_voice_adsp_callback_config_control[0].private_value =
904 rtd->dai_link->be_id;
905 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
906 ret = snd_soc_add_platform_controls(rtd->platform,
907 fe_voice_adsp_callback_config_control,
908 ARRAY_SIZE(fe_voice_adsp_callback_config_control));
910 pr_err("%s: failed to add ctl %s. err = %d\n",
911 __func__, mixer_str, ret);
916 kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
918 pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
923 kctl->private_data = NULL;
930 static struct snd_pcm_ops msm_pcm_ops = {
931 .open = msm_pcm_open,
932 .hw_params = msm_pcm_hw_params,
933 .close = msm_pcm_close,
934 .prepare = msm_pcm_prepare,
935 .trigger = msm_pcm_trigger,
936 .ioctl = msm_pcm_ioctl,
937 .compat_ioctl = msm_pcm_ioctl,
941 static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
943 struct snd_card *card = rtd->card->snd_card;
946 if (!card->dev->coherent_dma_mask)
947 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
949 ret = msm_pcm_add_voice_adsp_stream_cmd_control(rtd);
951 pr_err("%s: Could not add pcm ADSP Stream Cmd Control\n",
954 ret = msm_pcm_add_voice_adsp_stream_callback_control(rtd);
956 pr_err("%s: Could not add pcm ADSP Stream Callback Control\n",
962 static int msm_pcm_voice_probe(struct snd_soc_platform *platform)
964 snd_soc_add_platform_controls(platform, msm_voice_controls,
965 ARRAY_SIZE(msm_voice_controls));
970 static struct snd_soc_platform_driver msm_soc_platform = {
972 .pcm_new = msm_asoc_pcm_new,
973 .probe = msm_pcm_voice_probe,
976 static int msm_pcm_probe(struct platform_device *pdev)
979 bool destroy_cvd = false;
980 bool vote_bms = false;
981 const char *is_destroy_cvd = "qcom,destroy-cvd";
982 const char *is_vote_bms = "qcom,vote-bms";
984 if (!is_voc_initialized()) {
985 pr_debug("%s: voice module not initialized yet, deferring probe()\n",
992 rc = voc_alloc_cal_shared_memory();
993 if (rc == -EPROBE_DEFER) {
994 pr_debug("%s: memory allocation for calibration deferred %d\n",
999 pr_err("%s: memory allocation for calibration failed %d\n",
1003 pr_debug("%s: dev name %s\n",
1004 __func__, dev_name(&pdev->dev));
1005 destroy_cvd = of_property_read_bool(pdev->dev.of_node,
1007 voc_set_destroy_cvd_flag(destroy_cvd);
1009 vote_bms = of_property_read_bool(pdev->dev.of_node,
1011 voc_set_vote_bms_flag(vote_bms);
1013 rc = snd_soc_register_platform(&pdev->dev,
1020 static int msm_pcm_remove(struct platform_device *pdev)
1022 snd_soc_unregister_platform(&pdev->dev);
1026 static const struct of_device_id msm_voice_dt_match[] = {
1027 {.compatible = "qcom,msm-pcm-voice"},
1030 MODULE_DEVICE_TABLE(of, msm_voice_dt_match);
1032 static struct platform_driver msm_pcm_driver = {
1034 .name = "msm-pcm-voice",
1035 .owner = THIS_MODULE,
1036 .of_match_table = msm_voice_dt_match,
1038 .probe = msm_pcm_probe,
1039 .remove = msm_pcm_remove,
1042 static int __init msm_soc_platform_init(void)
1046 memset(&voice_info, 0, sizeof(voice_info));
1048 for (i = 0; i < VOICE_SESSION_INDEX_MAX; i++)
1049 mutex_init(&voice_info[i].lock);
1051 return platform_driver_register(&msm_pcm_driver);
1053 module_init(msm_soc_platform_init);
1055 static void __exit msm_soc_platform_exit(void)
1057 platform_driver_unregister(&msm_pcm_driver);
1059 module_exit(msm_soc_platform_exit);
1061 MODULE_DESCRIPTION("Voice PCM module platform driver");
1062 MODULE_LICENSE("GPL v2");