1 /* Copyright (c) 2012-2019, 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.
14 #include <linux/init.h>
15 #include <linux/err.h>
16 #include <linux/module.h>
17 #include <linux/moduleparam.h>
18 #include <linux/time.h>
19 #include <linux/wait.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 #include <sound/core.h>
23 #include <sound/soc.h>
24 #include <sound/soc-dapm.h>
25 #include <sound/pcm.h>
26 #include <sound/initval.h>
27 #include <sound/control.h>
28 #include <sound/q6audio-v2.h>
29 #include <sound/timer.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/msm_audio_ion.h>
33 #include <linux/msm_audio.h>
35 #include <linux/of_device.h>
36 #include <sound/tlv.h>
37 #include <sound/pcm_params.h>
38 #include <sound/q6core.h>
40 #include "msm-pcm-q6-v2.h"
41 #include "msm-pcm-routing-v2.h"
42 #include "msm-qti-pp-config.h"
50 static struct audio_locks the_locks;
52 #define PCM_MASTER_VOL_MAX_STEPS 0x2000
53 static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0,
54 PCM_MASTER_VOL_MAX_STEPS);
58 struct snd_card *card;
62 #define CMD_EOS_MIN_TIMEOUT_LENGTH 50
63 #define CMD_EOS_TIMEOUT_MULTIPLIER (HZ * 50)
64 #define MAX_PB_COPY_RETRIES 3
66 static struct snd_pcm_hardware msm_pcm_hardware_capture = {
67 .info = (SNDRV_PCM_INFO_MMAP |
68 SNDRV_PCM_INFO_BLOCK_TRANSFER |
69 SNDRV_PCM_INFO_MMAP_VALID |
70 SNDRV_PCM_INFO_INTERLEAVED |
71 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
72 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
73 SNDRV_PCM_FMTBIT_S24_LE |
74 SNDRV_PCM_FMTBIT_S24_3LE |
75 SNDRV_PCM_FMTBIT_S32_LE),
76 .rates = SNDRV_PCM_RATE_8000_384000,
81 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
82 CAPTURE_MAX_PERIOD_SIZE,
83 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
84 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
85 .periods_min = CAPTURE_MIN_NUM_PERIODS,
86 .periods_max = CAPTURE_MAX_NUM_PERIODS,
90 static struct snd_pcm_hardware msm_pcm_hardware_playback = {
91 .info = (SNDRV_PCM_INFO_MMAP |
92 SNDRV_PCM_INFO_BLOCK_TRANSFER |
93 SNDRV_PCM_INFO_MMAP_VALID |
94 SNDRV_PCM_INFO_INTERLEAVED |
95 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
96 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
97 SNDRV_PCM_FMTBIT_S24_LE |
98 SNDRV_PCM_FMTBIT_S24_3LE |
99 SNDRV_PCM_FMTBIT_S32_LE),
100 .rates = SNDRV_PCM_RATE_8000_384000,
105 .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS *
106 PLAYBACK_MAX_PERIOD_SIZE,
107 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
108 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
109 .periods_min = PLAYBACK_MIN_NUM_PERIODS,
110 .periods_max = PLAYBACK_MAX_NUM_PERIODS,
114 /* Conventional and unconventional sample rate supported */
115 static unsigned int supported_sample_rates[] = {
116 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
117 88200, 96000, 176400, 192000, 352800, 384000
120 static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
121 .count = ARRAY_SIZE(supported_sample_rates),
122 .list = supported_sample_rates,
126 static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
129 struct msm_audio *prtd = priv_data;
133 pr_debug("%s: event %x\n", __func__, event);
136 case MSM_PCM_RT_EVT_BUF_RECFG:
137 q6asm_cmd(prtd->audio_client, CMD_PAUSE);
138 q6asm_cmd(prtd->audio_client, CMD_FLUSH);
139 q6asm_run(prtd->audio_client, 0, 0, 0);
145 static void event_handler(uint32_t opcode,
146 uint32_t token, uint32_t *payload, void *priv)
148 struct msm_audio *prtd = priv;
149 struct snd_pcm_substream *substream = prtd->substream;
150 uint32_t *ptrmem = (uint32_t *)payload;
154 struct snd_soc_pcm_runtime *rtd;
158 case ASM_DATA_EVENT_WRITE_DONE_V2: {
159 pr_debug("ASM_DATA_EVENT_WRITE_DONE_V2\n");
160 pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
161 prtd->pcm_irq_pos += prtd->pcm_count;
162 if (atomic_read(&prtd->start))
163 snd_pcm_period_elapsed(substream);
164 atomic_inc(&prtd->out_count);
165 wake_up(&the_locks.write_wait);
166 if (!atomic_read(&prtd->start))
168 if (!prtd->mmap_flag || prtd->reset_event)
170 if (q6asm_is_cpu_buf_avail_nolock(IN,
173 pr_debug("%s:writing %d bytes of buffer to dsp 2\n",
174 __func__, prtd->pcm_count);
175 q6asm_write_nolock(prtd->audio_client,
176 prtd->pcm_count, 0, 0, NO_TIMESTAMP);
180 case ASM_DATA_EVENT_RENDERED_EOS:
181 pr_debug("ASM_DATA_EVENT_RENDERED_EOS\n");
182 clear_bit(CMD_EOS, &prtd->cmd_pending);
183 wake_up(&the_locks.eos_wait);
185 case ASM_DATA_EVENT_READ_DONE_V2: {
186 pr_debug("ASM_DATA_EVENT_READ_DONE_V2\n");
187 buf_index = q6asm_get_buf_index_from_token(token);
188 if (buf_index >= CAPTURE_MAX_NUM_PERIODS) {
189 pr_err("%s: buffer index %u is out of range.\n",
190 __func__, buf_index);
193 pr_debug("%s: token=0x%08x buf_index=0x%08x\n",
194 __func__, token, buf_index);
195 prtd->in_frame_info[buf_index].size = payload[4];
196 prtd->in_frame_info[buf_index].offset = payload[5];
197 /* assume data size = 0 during flushing */
198 if (prtd->in_frame_info[buf_index].size) {
200 prtd->in_frame_info[buf_index].size;
201 pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
202 if (atomic_read(&prtd->start))
203 snd_pcm_period_elapsed(substream);
204 if (atomic_read(&prtd->in_count) <= prtd->periods)
205 atomic_inc(&prtd->in_count);
206 wake_up(&the_locks.read_wait);
207 if (prtd->mmap_flag &&
208 q6asm_is_cpu_buf_avail_nolock(OUT,
211 (substream->runtime->status->state ==
212 SNDRV_PCM_STATE_RUNNING))
213 q6asm_read_nolock(prtd->audio_client);
215 pr_debug("%s: reclaim flushed buf in_count %x\n",
216 __func__, atomic_read(&prtd->in_count));
217 prtd->pcm_irq_pos += prtd->pcm_count;
218 if (prtd->mmap_flag) {
219 if (q6asm_is_cpu_buf_avail_nolock(OUT,
222 (substream->runtime->status->state ==
223 SNDRV_PCM_STATE_RUNNING))
224 q6asm_read_nolock(prtd->audio_client);
226 atomic_inc(&prtd->in_count);
228 if (atomic_read(&prtd->in_count) == prtd->periods) {
229 pr_info("%s: reclaimed all bufs\n", __func__);
230 if (atomic_read(&prtd->start))
231 snd_pcm_period_elapsed(substream);
232 wake_up(&the_locks.read_wait);
237 case ASM_STREAM_PP_EVENT:
238 case ASM_STREAM_CMD_ENCDEC_EVENTS: {
239 pr_debug("%s: ASM_STREAM_EVENT (0x%x)\n", __func__, opcode);
241 pr_err("%s: substream is NULL.\n", __func__);
245 rtd = substream->private_data;
247 pr_err("%s: rtd is NULL\n", __func__);
251 ret = msm_adsp_inform_mixer_ctl(rtd, payload);
253 pr_err("%s: failed to inform mixer ctl. err = %d\n",
260 case APR_BASIC_RSP_RESULT: {
261 switch (payload[0]) {
262 case ASM_SESSION_CMD_RUN_V2:
263 if (substream->stream
264 != SNDRV_PCM_STREAM_PLAYBACK) {
265 atomic_set(&prtd->start, 1);
268 if (prtd->mmap_flag) {
269 pr_debug("%s:writing %d bytes of buffer to dsp\n",
272 q6asm_write_nolock(prtd->audio_client,
276 while (atomic_read(&prtd->out_needed)) {
277 pr_debug("%s:writing %d bytes of buffer to dsp\n",
280 q6asm_write_nolock(prtd->audio_client,
283 atomic_dec(&prtd->out_needed);
284 wake_up(&the_locks.write_wait);
287 atomic_set(&prtd->start, 1);
289 case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
290 pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:",
294 pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
295 __func__, payload[0], payload[1]);
301 pr_debug("%s RESET_EVENTS\n", __func__);
302 prtd->pcm_irq_pos += prtd->pcm_count;
303 atomic_inc(&prtd->out_count);
304 atomic_inc(&prtd->in_count);
305 prtd->reset_event = true;
306 if (atomic_read(&prtd->start))
307 snd_pcm_period_elapsed(substream);
308 wake_up(&the_locks.eos_wait);
309 wake_up(&the_locks.write_wait);
310 wake_up(&the_locks.read_wait);
313 pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
318 static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
320 struct snd_pcm_runtime *runtime = substream->runtime;
321 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
322 struct msm_audio *prtd = runtime->private_data;
323 struct msm_plat_data *pdata;
324 struct snd_pcm_hw_params *params;
326 uint32_t fmt_type = FORMAT_LINEAR_PCM;
327 uint16_t bits_per_sample;
328 uint16_t sample_word_size;
330 pdata = (struct msm_plat_data *)
331 dev_get_drvdata(soc_prtd->platform->dev);
333 pr_err("%s: platform data not populated\n", __func__);
336 if (!prtd || !prtd->audio_client) {
337 pr_err("%s: private data null or audio client freed\n",
341 params = &soc_prtd->dpcm[substream->stream].hw_params;
343 pr_debug("%s\n", __func__);
344 prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
345 prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
346 prtd->pcm_irq_pos = 0;
347 /* rate and channels are sent to audio driver */
348 prtd->samp_rate = runtime->rate;
349 prtd->channel_mode = runtime->channels;
353 prtd->audio_client->perf_mode = pdata->perf_mode;
354 pr_debug("%s: perf: %x\n", __func__, pdata->perf_mode);
356 switch (params_format(params)) {
357 case SNDRV_PCM_FORMAT_S32_LE:
358 bits_per_sample = 32;
359 sample_word_size = 32;
361 case SNDRV_PCM_FORMAT_S24_LE:
362 bits_per_sample = 24;
363 sample_word_size = 32;
365 case SNDRV_PCM_FORMAT_S24_3LE:
366 bits_per_sample = 24;
367 sample_word_size = 24;
369 case SNDRV_PCM_FORMAT_S16_LE:
371 bits_per_sample = 16;
372 sample_word_size = 16;
375 if (prtd->compress_enable) {
376 fmt_type = FORMAT_GEN_COMPR;
377 pr_debug("%s: Compressed enabled!\n", __func__);
378 ret = q6asm_open_write_compressed(prtd->audio_client, fmt_type,
379 COMPRESSED_PASSTHROUGH_GEN);
381 pr_err("%s: q6asm_open_write_compressed failed (%d)\n",
383 q6asm_audio_client_free(prtd->audio_client);
384 prtd->audio_client = NULL;
387 } else if (pdata->avs_ver &&
388 (q6core_get_avs_version() == Q6_SUBSYS_AVS2_7)) {
389 ret = q6asm_open_write_v3(prtd->audio_client,
390 FORMAT_LINEAR_PCM, bits_per_sample);
392 pr_err("%s: q6asm_open_write_v3 failed (%d)\n",
394 q6asm_audio_client_free(prtd->audio_client);
395 prtd->audio_client = NULL;
399 ret = q6asm_open_write_with_retry(prtd->audio_client,
400 fmt_type, bits_per_sample);
402 pr_err("%s: q6asm_open_write_with_retry failed (%d)\n",
404 q6asm_audio_client_free(prtd->audio_client);
405 prtd->audio_client = NULL;
409 ret = q6asm_send_cal(prtd->audio_client);
411 pr_debug("%s : Send cal failed : %d", __func__, ret);
413 pr_debug("%s: session ID %d\n", __func__,
414 prtd->audio_client->session);
415 prtd->session_id = prtd->audio_client->session;
417 if (prtd->compress_enable) {
418 ret = msm_pcm_routing_reg_phy_compr_stream(
419 soc_prtd->dai_link->be_id,
420 prtd->audio_client->perf_mode,
422 SNDRV_PCM_STREAM_PLAYBACK,
423 COMPRESSED_PASSTHROUGH_GEN);
425 ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
426 prtd->audio_client->perf_mode,
427 prtd->session_id, substream->stream);
430 pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
433 if (prtd->compress_enable) {
434 ret = q6asm_media_format_block_gen_compr(
435 prtd->audio_client, runtime->rate,
436 runtime->channels, !prtd->set_channel_map,
437 prtd->channel_map, bits_per_sample);
439 if (q6asm_get_svc_version(APR_SVC_ASM) >=
440 ADSP_ASM_API_VERSION_V2)
441 ret = q6asm_media_format_block_multi_ch_pcm_v5(
442 prtd->audio_client, runtime->rate,
443 runtime->channels, !prtd->set_channel_map,
444 prtd->channel_map, bits_per_sample,
445 sample_word_size, ASM_LITTLE_ENDIAN,
447 else if (pdata->avs_ver &&
448 (q6core_get_avs_version() ==
450 ret = q6asm_media_format_block_multi_ch_pcm_v3(
451 prtd->audio_client, runtime->rate,
452 runtime->channels, !prtd->set_channel_map,
453 prtd->channel_map, bits_per_sample,
456 ret = q6asm_media_format_block_multi_ch_pcm_v4(
457 prtd->audio_client, runtime->rate,
458 runtime->channels, !prtd->set_channel_map,
459 prtd->channel_map, bits_per_sample,
460 sample_word_size, ASM_LITTLE_ENDIAN,
464 pr_info("%s: CMD Format block failed\n", __func__);
466 atomic_set(&prtd->out_count, runtime->periods);
469 prtd->cmd_pending = 0;
470 prtd->cmd_interrupt = 0;
475 static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
477 struct snd_pcm_runtime *runtime = substream->runtime;
478 struct msm_audio *prtd = runtime->private_data;
479 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
480 struct msm_plat_data *pdata;
481 struct snd_pcm_hw_params *params;
482 struct msm_pcm_routing_evt event;
485 uint16_t bits_per_sample = 16;
486 uint16_t sample_word_size;
488 pdata = (struct msm_plat_data *)
489 dev_get_drvdata(soc_prtd->platform->dev);
491 pr_err("%s: platform data not populated\n", __func__);
494 if (!prtd || !prtd->audio_client) {
495 pr_err("%s: private data null or audio client freed\n",
500 if (prtd->enabled == IDLE) {
501 pr_debug("%s:perf_mode=%d periods=%d\n", __func__,
502 pdata->perf_mode, runtime->periods);
503 params = &soc_prtd->dpcm[substream->stream].hw_params;
504 if ((params_format(params) == SNDRV_PCM_FORMAT_S24_LE) ||
505 (params_format(params) == SNDRV_PCM_FORMAT_S24_3LE))
506 bits_per_sample = 24;
507 else if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
508 bits_per_sample = 32;
510 /* ULL mode is not supported in capture path */
511 if (pdata->perf_mode == LEGACY_PCM_MODE)
512 prtd->audio_client->perf_mode = LEGACY_PCM_MODE;
514 prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE;
516 pr_debug("%s Opening %d-ch PCM read stream, perf_mode %d\n",
517 __func__, params_channels(params),
518 prtd->audio_client->perf_mode);
519 if (pdata->avs_ver &&
520 (q6core_get_avs_version() == Q6_SUBSYS_AVS2_7))
521 ret = q6asm_open_read_v3(prtd->audio_client,
525 ret = q6asm_open_read_with_retry(prtd->audio_client,
527 bits_per_sample, false);
529 pr_err("%s: q6asm_open_read failed\n", __func__);
530 q6asm_audio_client_free(prtd->audio_client);
531 prtd->audio_client = NULL;
535 ret = q6asm_send_cal(prtd->audio_client);
537 pr_debug("%s : Send cal failed : %d", __func__, ret);
539 pr_debug("%s: session ID %d\n",
540 __func__, prtd->audio_client->session);
541 prtd->session_id = prtd->audio_client->session;
542 event.event_func = msm_pcm_route_event_handler;
543 event.priv_data = (void *) prtd;
544 ret = msm_pcm_routing_reg_phy_stream_v2(
545 soc_prtd->dai_link->be_id,
546 prtd->audio_client->perf_mode,
547 prtd->session_id, substream->stream,
550 pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
555 prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
556 prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
557 prtd->pcm_irq_pos = 0;
558 /* rate and channels are sent to audio driver */
559 prtd->samp_rate = runtime->rate;
560 prtd->channel_mode = runtime->channels;
562 if (prtd->enabled == IDLE || prtd->enabled == STOPPED) {
563 for (i = 0; i < runtime->periods; i++)
564 q6asm_read(prtd->audio_client);
565 prtd->periods = runtime->periods;
568 if (prtd->enabled != IDLE)
571 switch (runtime->format) {
572 case SNDRV_PCM_FORMAT_S32_LE:
573 bits_per_sample = 32;
574 sample_word_size = 32;
576 case SNDRV_PCM_FORMAT_S24_LE:
577 bits_per_sample = 24;
578 sample_word_size = 32;
580 case SNDRV_PCM_FORMAT_S24_3LE:
581 bits_per_sample = 24;
582 sample_word_size = 24;
584 case SNDRV_PCM_FORMAT_S16_LE:
586 bits_per_sample = 16;
587 sample_word_size = 16;
591 pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
592 __func__, prtd->samp_rate, prtd->channel_mode,
593 bits_per_sample, sample_word_size);
594 if (q6asm_get_svc_version(APR_SVC_ASM) >=
595 ADSP_ASM_API_VERSION_V2)
596 ret = q6asm_enc_cfg_blk_pcm_format_support_v5(
604 else if (pdata->avs_ver &&
605 (q6core_get_avs_version() ==
607 ret = q6asm_enc_cfg_blk_pcm_format_support_v3(
614 ret = q6asm_enc_cfg_blk_pcm_format_support_v4(
623 pr_debug("%s: cmd cfg pcm was block failed", __func__);
625 prtd->enabled = RUNNING;
630 static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
633 struct snd_pcm_runtime *runtime = substream->runtime;
634 struct msm_audio *prtd = runtime->private_data;
637 case SNDRV_PCM_TRIGGER_START:
638 case SNDRV_PCM_TRIGGER_RESUME:
639 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
640 pr_debug("%s: Trigger start\n", __func__);
641 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
643 case SNDRV_PCM_TRIGGER_STOP:
644 pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
645 atomic_set(&prtd->start, 0);
646 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
647 prtd->enabled = STOPPED;
648 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
651 /* pending CMD_EOS isn't expected */
652 WARN_ON_ONCE(test_bit(CMD_EOS, &prtd->cmd_pending));
653 set_bit(CMD_EOS, &prtd->cmd_pending);
654 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
656 clear_bit(CMD_EOS, &prtd->cmd_pending);
658 case SNDRV_PCM_TRIGGER_SUSPEND:
659 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
660 pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n");
661 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
662 atomic_set(&prtd->start, 0);
672 static int msm_pcm_open(struct snd_pcm_substream *substream)
674 struct snd_pcm_runtime *runtime = substream->runtime;
675 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
676 struct msm_audio *prtd;
677 struct msm_plat_data *pdata;
680 pdata = (struct msm_plat_data *)
681 dev_get_drvdata(soc_prtd->platform->dev);
683 pr_err("%s: platform data not populated\n", __func__);
686 prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL);
688 pr_err("Failed to allocate memory for msm_audio\n");
691 prtd->substream = substream;
692 prtd->audio_client = q6asm_audio_client_alloc(
693 (app_cb)event_handler, prtd);
694 if (!prtd->audio_client) {
695 pr_info("%s: Could not allocate memory\n", __func__);
701 prtd->audio_client->dev = soc_prtd->platform->dev;
703 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
704 runtime->hw = msm_pcm_hardware_playback;
707 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
708 runtime->hw = msm_pcm_hardware_capture;
710 pr_err("Invalid Stream type %d\n", substream->stream);
714 ret = snd_pcm_hw_constraint_list(runtime, 0,
715 SNDRV_PCM_HW_PARAM_RATE,
716 &constraints_sample_rates);
718 pr_info("snd_pcm_hw_constraint_list failed\n");
719 /* Ensure that buffer size is a multiple of period size */
720 ret = snd_pcm_hw_constraint_integer(runtime,
721 SNDRV_PCM_HW_PARAM_PERIODS);
723 pr_info("snd_pcm_hw_constraint_integer failed\n");
725 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
726 ret = snd_pcm_hw_constraint_minmax(runtime,
727 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
728 PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE,
729 PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE);
731 pr_err("constraint for buffer bytes min max ret = %d\n",
736 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
737 ret = snd_pcm_hw_constraint_minmax(runtime,
738 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
739 CAPTURE_MIN_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE,
740 CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE);
742 pr_err("constraint for buffer bytes min max ret = %d\n",
746 ret = snd_pcm_hw_constraint_step(runtime, 0,
747 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
749 pr_err("constraint for period bytes step ret = %d\n",
752 ret = snd_pcm_hw_constraint_step(runtime, 0,
753 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
755 pr_err("constraint for buffer bytes step ret = %d\n",
759 prtd->enabled = IDLE;
761 prtd->set_channel_map = false;
762 prtd->reset_event = false;
763 runtime->private_data = prtd;
764 msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd);
765 /* Vote to update the Rx thread priority to RT Thread for playback */
766 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
767 (pdata->perf_mode == LOW_LATENCY_PCM_MODE))
768 apr_start_rx_rt(prtd->audio_client->apr);
770 /* Vote to update the Rx thread priority to RT Thread for playback */
771 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
772 (pdata->perf_mode == LOW_LATENCY_PCM_MODE))
773 apr_start_rx_rt(prtd->audio_client->apr);
778 static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
779 snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
788 uint32_t retries = 0;
790 struct snd_pcm_runtime *runtime = substream->runtime;
791 struct msm_audio *prtd = runtime->private_data;
793 fbytes = frames_to_bytes(runtime, frames);
794 pr_debug("%s: prtd->out_count = %d\n",
795 __func__, atomic_read(&prtd->out_count));
797 while ((fbytes > 0) && (retries < MAX_PB_COPY_RETRIES)) {
798 if (prtd->reset_event) {
799 pr_err("%s: In SSR return ENETRESET before wait\n",
804 ret = wait_event_timeout(the_locks.write_wait,
805 (atomic_read(&prtd->out_count)), 5 * HZ);
807 pr_err("%s: wait_event_timeout failed\n", __func__);
813 if (prtd->reset_event) {
814 pr_err("%s: In SSR return ENETRESET after wait\n",
819 if (!atomic_read(&prtd->out_count)) {
820 pr_err("%s: pcm stopped out_count 0\n", __func__);
824 data = q6asm_is_cpu_buf_avail(IN, prtd->audio_client, &size,
840 pr_debug("%s:fbytes =%d: xfer=%d size=%d\n",
841 __func__, fbytes, xfer, size);
842 if (copy_from_user(bufptr, buf, xfer)) {
844 pr_err("%s: copy_from_user failed\n",
846 q6asm_cpu_buf_release(IN, prtd->audio_client);
851 pr_debug("%s:fbytes = %d: xfer=%d\n", __func__, fbytes,
853 if (atomic_read(&prtd->start)) {
854 pr_debug("%s:writing %d bytes of buffer to dsp\n",
856 ret = q6asm_write(prtd->audio_client, xfer,
860 q6asm_cpu_buf_release(IN,
865 atomic_inc(&prtd->out_needed);
866 atomic_dec(&prtd->out_count);
870 if (retries >= MAX_PB_COPY_RETRIES)
876 static int msm_pcm_playback_close(struct snd_pcm_substream *substream)
878 struct snd_pcm_runtime *runtime = substream->runtime;
879 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
880 struct msm_audio *prtd = runtime->private_data;
881 struct msm_plat_data *pdata;
886 pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending);
888 if (prtd->audio_client) {
892 * Unvote to downgrade the Rx thread priority from
893 * RT Thread for Low-Latency use case.
895 pdata = (struct msm_plat_data *)
896 dev_get_drvdata(soc_prtd->platform->dev);
898 if (pdata->perf_mode == LOW_LATENCY_PCM_MODE)
899 apr_end_rx_rt(prtd->audio_client->apr);
901 /* determine timeout length */
902 if (runtime->frame_bits == 0 || runtime->rate == 0) {
903 timeout = CMD_EOS_MIN_TIMEOUT_LENGTH;
905 timeout = (runtime->period_size *
906 CMD_EOS_TIMEOUT_MULTIPLIER) /
907 ((runtime->frame_bits / 8) *
909 if (timeout < CMD_EOS_MIN_TIMEOUT_LENGTH)
910 timeout = CMD_EOS_MIN_TIMEOUT_LENGTH;
912 pr_debug("%s: CMD_EOS timeout is %d\n", __func__, timeout);
914 ret = wait_event_timeout(the_locks.eos_wait,
915 !test_bit(CMD_EOS, &prtd->cmd_pending),
918 pr_err("%s: CMD_EOS failed, cmd_pending 0x%lx\n",
919 __func__, prtd->cmd_pending);
920 q6asm_cmd(prtd->audio_client, CMD_CLOSE);
921 q6asm_audio_client_buf_free_contiguous(dir,
923 q6asm_audio_client_free(prtd->audio_client);
925 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
926 SNDRV_PCM_STREAM_PLAYBACK);
927 msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd);
929 runtime->private_data = NULL;
934 static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
935 int channel, snd_pcm_uframes_t hwoff, void __user *buf,
936 snd_pcm_uframes_t frames)
944 static uint32_t size;
946 struct snd_pcm_runtime *runtime = substream->runtime;
947 struct msm_audio *prtd = substream->runtime->private_data;
950 pr_debug("%s\n", __func__);
951 fbytes = frames_to_bytes(runtime, frames);
953 pr_debug("appl_ptr %d\n", (int)runtime->control->appl_ptr);
954 pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr);
955 pr_debug("avail_min %d\n", (int)runtime->control->avail_min);
957 if (prtd->reset_event) {
958 pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
961 ret = wait_event_timeout(the_locks.read_wait,
962 (atomic_read(&prtd->in_count)), 5 * HZ);
964 pr_debug("%s: wait_event_timeout failed\n", __func__);
967 if (prtd->reset_event) {
968 pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
971 if (!atomic_read(&prtd->in_count)) {
972 pr_debug("%s: pcm stopped in_count 0\n", __func__);
975 pr_debug("Checking if valid buffer is available...%pK\n",
977 data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx);
979 pr_debug("Size = %d\n", size);
980 pr_debug("fbytes = %d\n", fbytes);
981 pr_debug("idx = %d\n", idx);
986 offset = prtd->in_frame_info[idx].offset;
987 pr_debug("Offset value = %d\n", offset);
988 if (copy_to_user(buf, bufptr+offset, xfer)) {
989 pr_err("Failed to copy buf to user\n");
991 q6asm_cpu_buf_release(OUT, prtd->audio_client);
996 prtd->in_frame_info[idx].offset += xfer;
997 pr_debug("%s:fbytes = %d: size=%d: xfer=%d\n",
998 __func__, fbytes, size, xfer);
999 pr_debug(" Sending next buffer to dsp\n");
1000 memset(&prtd->in_frame_info[idx], 0,
1001 sizeof(struct msm_audio_in_frame_info));
1002 atomic_dec(&prtd->in_count);
1003 ret = q6asm_read(prtd->audio_client);
1005 pr_err("q6asm read failed\n");
1007 q6asm_cpu_buf_release(OUT, prtd->audio_client);
1011 pr_err("No valid buffer\n");
1013 pr_debug("Returning from capture_copy... %d\n", ret);
1018 static int msm_pcm_capture_close(struct snd_pcm_substream *substream)
1020 struct snd_pcm_runtime *runtime = substream->runtime;
1021 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
1022 struct msm_audio *prtd = runtime->private_data;
1025 pr_debug("%s\n", __func__);
1026 if (prtd->audio_client) {
1027 q6asm_cmd(prtd->audio_client, CMD_CLOSE);
1028 q6asm_audio_client_buf_free_contiguous(dir,
1029 prtd->audio_client);
1030 q6asm_audio_client_free(prtd->audio_client);
1033 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
1034 SNDRV_PCM_STREAM_CAPTURE);
1036 runtime->private_data = NULL;
1041 static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
1042 snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
1046 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1047 ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames);
1048 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1049 ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
1053 static int msm_pcm_close(struct snd_pcm_substream *substream)
1057 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1058 ret = msm_pcm_playback_close(substream);
1059 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1060 ret = msm_pcm_capture_close(substream);
1064 static int msm_pcm_prepare(struct snd_pcm_substream *substream)
1068 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1069 ret = msm_pcm_playback_prepare(substream);
1070 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1071 ret = msm_pcm_capture_prepare(substream);
1075 static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
1078 struct snd_pcm_runtime *runtime = substream->runtime;
1079 struct msm_audio *prtd = runtime->private_data;
1081 if (prtd->pcm_irq_pos >= prtd->pcm_size)
1082 prtd->pcm_irq_pos = 0;
1084 pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
1085 return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
1088 static int msm_pcm_mmap(struct snd_pcm_substream *substream,
1089 struct vm_area_struct *vma)
1091 struct snd_pcm_runtime *runtime = substream->runtime;
1092 struct msm_audio *prtd = runtime->private_data;
1093 struct audio_client *ac = prtd->audio_client;
1094 struct audio_port_data *apd = ac->port;
1095 struct audio_buffer *ab;
1098 prtd->mmap_flag = 1;
1100 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1104 ab = &(apd[dir].buf[0]);
1106 return msm_audio_ion_mmap(ab, vma);
1109 static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
1110 struct snd_pcm_hw_params *params)
1112 struct snd_pcm_runtime *runtime = substream->runtime;
1113 struct msm_audio *prtd = runtime->private_data;
1114 struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
1115 struct audio_buffer *buf;
1118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1122 ret = q6asm_audio_client_buf_alloc_contiguous(dir,
1124 (params_buffer_bytes(params) / params_periods(params)),
1125 params_periods(params));
1127 pr_err("Audio Start: Buffer Allocation failed rc = %d\n",
1131 buf = prtd->audio_client->port[dir].buf;
1132 if (buf == NULL || buf[0].data == NULL)
1135 pr_debug("%s:buf = %pK\n", __func__, buf);
1136 dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
1137 dma_buf->dev.dev = substream->pcm->card->dev;
1138 dma_buf->private_data = NULL;
1139 dma_buf->area = buf[0].data;
1140 dma_buf->addr = buf[0].phys;
1141 dma_buf->bytes = params_buffer_bytes(params);
1145 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
1149 static struct snd_pcm_ops msm_pcm_ops = {
1150 .open = msm_pcm_open,
1151 .copy = msm_pcm_copy,
1152 .hw_params = msm_pcm_hw_params,
1153 .close = msm_pcm_close,
1154 .ioctl = snd_pcm_lib_ioctl,
1155 .prepare = msm_pcm_prepare,
1156 .trigger = msm_pcm_trigger,
1157 .pointer = msm_pcm_pointer,
1158 .mmap = msm_pcm_mmap,
1161 static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
1162 struct snd_ctl_elem_value *ucontrol)
1164 struct snd_soc_component *pcm = snd_kcontrol_chip(kcontrol);
1165 struct snd_soc_platform *platform = snd_soc_component_to_platform(pcm);
1166 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
1167 struct snd_pcm_substream *substream;
1168 struct msm_audio *prtd;
1170 struct msm_adsp_event_data *event_data = NULL;
1171 uint64_t actual_payload_len = 0;
1174 pr_err("%s pdata is NULL\n", __func__);
1179 substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1181 pr_err("%s substream not found\n", __func__);
1186 if (!substream->runtime) {
1187 pr_err("%s substream runtime not found\n", __func__);
1192 prtd = substream->runtime->private_data;
1194 pr_err("%s prtd is null.\n", __func__);
1199 if (prtd->audio_client == NULL) {
1200 pr_err("%s prtd is null.\n", __func__);
1205 event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
1206 if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
1207 (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
1208 pr_err("%s: invalid event_type=%d",
1209 __func__, event_data->event_type);
1214 actual_payload_len = sizeof(struct msm_adsp_event_data) +
1215 event_data->payload_len;
1216 if (actual_payload_len >= U32_MAX) {
1217 pr_err("%s payload length 0x%X exceeds limit",
1218 __func__, event_data->payload_len);
1223 if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
1224 - sizeof(struct msm_adsp_event_data)) {
1225 pr_err("%s param length=%d exceeds limit",
1226 __func__, event_data->payload_len);
1231 ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
1233 pr_err("%s: failed to send stream event cmd, err = %d\n",
1239 static int msm_pcm_add_audio_adsp_stream_cmd_control(
1240 struct snd_soc_pcm_runtime *rtd)
1242 const char *mixer_ctl_name = DSP_STREAM_CMD;
1243 const char *deviceNo = "NN";
1244 char *mixer_str = NULL;
1245 int ctl_len = 0, ret = 0;
1246 struct snd_kcontrol_new fe_audio_adsp_stream_cmd_config_control[1] = {
1248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1250 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1251 .info = msm_adsp_stream_cmd_info,
1252 .put = msm_pcm_adsp_stream_cmd_put,
1258 pr_err("%s rtd is NULL\n", __func__);
1263 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
1264 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1270 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
1271 fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str;
1272 fe_audio_adsp_stream_cmd_config_control[0].private_value =
1273 rtd->dai_link->be_id;
1274 pr_debug("Registering new mixer ctl %s\n", mixer_str);
1275 ret = snd_soc_add_platform_controls(rtd->platform,
1276 fe_audio_adsp_stream_cmd_config_control,
1277 ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control));
1279 pr_err("%s: failed add ctl %s. err = %d\n",
1280 __func__, mixer_str, ret);
1287 static int msm_pcm_add_audio_adsp_stream_callback_control(
1288 struct snd_soc_pcm_runtime *rtd)
1290 const char *mixer_ctl_name = DSP_STREAM_CALLBACK;
1291 const char *deviceNo = "NN";
1292 char *mixer_str = NULL;
1293 int ctl_len = 0, ret = 0;
1294 struct snd_kcontrol *kctl;
1296 struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = {
1298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1300 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1301 .info = msm_adsp_stream_callback_info,
1302 .get = msm_adsp_stream_callback_get,
1308 pr_err("%s NULL rtd\n", __func__);
1313 pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n",
1314 __func__, rtd->dai_link->name, rtd->dai_link->be_id,
1315 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
1316 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
1317 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1323 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
1324 fe_audio_adsp_callback_config_control[0].name = mixer_str;
1325 fe_audio_adsp_callback_config_control[0].private_value =
1326 rtd->dai_link->be_id;
1327 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
1328 ret = snd_soc_add_platform_controls(rtd->platform,
1329 fe_audio_adsp_callback_config_control,
1330 ARRAY_SIZE(fe_audio_adsp_callback_config_control));
1332 pr_err("%s: failed to add ctl %s. err = %d\n",
1333 __func__, mixer_str, ret);
1335 goto free_mixer_str;
1338 kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
1340 pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
1342 goto free_mixer_str;
1345 kctl->private_data = NULL;
1353 static int msm_pcm_set_volume(struct msm_audio *prtd, uint32_t volume)
1357 if (prtd && prtd->audio_client) {
1358 pr_debug("%s: channels %d volume 0x%x\n", __func__,
1359 prtd->channel_mode, volume);
1360 rc = q6asm_set_volume(prtd->audio_client, volume);
1362 pr_err("%s: Send Volume command failed rc=%d\n",
1369 static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol,
1370 struct snd_ctl_elem_value *ucontrol)
1372 struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol);
1373 struct snd_pcm_substream *substream =
1374 vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1375 struct msm_audio *prtd;
1377 pr_debug("%s\n", __func__);
1379 pr_err("%s substream not found\n", __func__);
1382 if (!substream->runtime) {
1383 pr_err("%s substream runtime not found\n", __func__);
1386 prtd = substream->runtime->private_data;
1388 ucontrol->value.integer.value[0] = prtd->volume;
1392 static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
1393 struct snd_ctl_elem_value *ucontrol)
1396 struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol);
1397 struct snd_pcm_substream *substream =
1398 vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1399 struct msm_audio *prtd;
1400 int volume = ucontrol->value.integer.value[0];
1402 pr_debug("%s: volume : 0x%x\n", __func__, volume);
1404 pr_err("%s substream not found\n", __func__);
1407 if (!substream->runtime) {
1408 pr_err("%s substream runtime not found\n", __func__);
1411 prtd = substream->runtime->private_data;
1413 rc = msm_pcm_set_volume(prtd, volume);
1414 prtd->volume = volume;
1419 static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd)
1422 struct snd_pcm *pcm = rtd->pcm;
1423 struct snd_pcm_volume *volume_info;
1424 struct snd_kcontrol *kctl;
1426 dev_dbg(rtd->dev, "%s, Volume control add\n", __func__);
1427 ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1428 NULL, 1, rtd->dai_link->be_id,
1431 pr_err("%s volume control failed ret %d\n", __func__, ret);
1434 kctl = volume_info->kctl;
1435 kctl->put = msm_pcm_volume_ctl_put;
1436 kctl->get = msm_pcm_volume_ctl_get;
1437 kctl->tlv.p = msm_pcm_vol_gain;
1441 static int msm_pcm_compress_ctl_info(struct snd_kcontrol *kcontrol,
1442 struct snd_ctl_elem_info *uinfo)
1444 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1446 uinfo->value.integer.min = 0;
1447 uinfo->value.integer.max = 0x2000;
1451 static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
1452 struct snd_ctl_elem_value *ucontrol)
1454 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
1455 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
1456 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
1457 struct snd_pcm_substream *substream;
1458 struct msm_audio *prtd;
1461 pr_err("%s pdata is NULL\n", __func__);
1464 substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1466 pr_err("%s substream not found\n", __func__);
1469 if (!substream->runtime) {
1470 pr_err("%s substream runtime not found\n", __func__);
1473 prtd = substream->runtime->private_data;
1475 ucontrol->value.integer.value[0] = prtd->compress_enable;
1479 static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
1480 struct snd_ctl_elem_value *ucontrol)
1483 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
1484 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
1485 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
1486 struct snd_pcm_substream *substream;
1487 struct msm_audio *prtd;
1488 int compress = ucontrol->value.integer.value[0];
1491 pr_err("%s pdata is NULL\n", __func__);
1494 substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1495 pr_debug("%s: compress : 0x%x\n", __func__, compress);
1497 pr_err("%s substream not found\n", __func__);
1500 if (!substream->runtime) {
1501 pr_err("%s substream runtime not found\n", __func__);
1504 prtd = substream->runtime->private_data;
1506 pr_debug("%s: setting compress flag to 0x%x\n",
1507 __func__, compress);
1508 prtd->compress_enable = compress;
1513 static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
1515 const char *mixer_ctl_name = "Playback ";
1516 const char *mixer_ctl_end_name = " Compress";
1517 const char *deviceNo = "NN";
1518 char *mixer_str = NULL;
1521 struct msm_plat_data *pdata;
1522 struct snd_kcontrol_new pcm_compress_control[1] = {
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1526 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1527 .info = msm_pcm_compress_ctl_info,
1528 .get = msm_pcm_compress_ctl_get,
1529 .put = msm_pcm_compress_ctl_put,
1535 pr_err("%s: NULL rtd\n", __func__);
1539 ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) +
1540 strlen(mixer_ctl_end_name) + 1;
1541 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1546 snprintf(mixer_str, ctl_len, "%s%d%s", mixer_ctl_name,
1547 rtd->pcm->device, mixer_ctl_end_name);
1549 pcm_compress_control[0].name = mixer_str;
1550 pcm_compress_control[0].private_value = rtd->dai_link->be_id;
1551 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
1552 pdata = dev_get_drvdata(rtd->platform->dev);
1555 pdata->pcm = rtd->pcm;
1556 ret = snd_soc_add_platform_controls(rtd->platform,
1557 pcm_compress_control,
1559 (pcm_compress_control));
1561 pr_err("%s: failed add ctl %s. err = %d\n",
1562 __func__, mixer_str, ret);
1565 pr_err("%s: NULL pdata\n", __func__);
1572 static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1573 struct snd_ctl_elem_value *ucontrol)
1576 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1577 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1578 struct snd_pcm_substream *substream;
1579 struct msm_audio *prtd;
1581 pr_debug("%s", __func__);
1582 substream = snd_pcm_chmap_substream(info, idx);
1585 if (!substream->runtime)
1588 prtd = substream->runtime->private_data;
1590 prtd->set_channel_map = true;
1591 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
1592 prtd->channel_map[i] =
1593 (char)(ucontrol->value.integer.value[i]);
1598 static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol)
1602 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
1603 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1604 struct snd_pcm_substream *substream;
1605 struct msm_audio *prtd;
1607 pr_debug("%s", __func__);
1608 substream = snd_pcm_chmap_substream(info, idx);
1611 memset(ucontrol->value.integer.value, 0,
1612 sizeof(ucontrol->value.integer.value));
1613 if (!substream->runtime)
1614 return 0; /* no channels set */
1616 prtd = substream->runtime->private_data;
1618 if (prtd && prtd->set_channel_map == true) {
1619 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
1620 ucontrol->value.integer.value[i] =
1621 (int)prtd->channel_map[i];
1623 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
1624 ucontrol->value.integer.value[i] = 0;
1630 static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
1632 struct snd_pcm *pcm = rtd->pcm;
1633 struct snd_pcm_chmap *chmap_info;
1634 struct snd_kcontrol *kctl;
1635 char device_num[12];
1638 pr_debug("%s, Channel map cntrl add\n", __func__);
1639 ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1641 PCM_FORMAT_MAX_NUM_CHANNEL_V2, 0,
1644 pr_err("%s, channel map cntrl add failed\n", __func__);
1647 kctl = chmap_info->kctl;
1648 for (i = 0; i < kctl->count; i++)
1649 kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
1650 snprintf(device_num, sizeof(device_num), "%d", pcm->device);
1651 strlcat(kctl->id.name, device_num, sizeof(kctl->id.name));
1652 pr_debug("%s, Overwriting channel map control name to: %s\n",
1653 __func__, kctl->id.name);
1654 kctl->put = msm_pcm_chmap_ctl_put;
1655 kctl->get = msm_pcm_chmap_ctl_get;
1659 static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
1660 struct snd_ctl_elem_value *ucontrol)
1662 u64 fe_id = kcontrol->private_value;
1663 int session_type = SESSION_TYPE_RX;
1664 int be_id = ucontrol->value.integer.value[3];
1665 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0};
1668 cfg_data.app_type = ucontrol->value.integer.value[0];
1669 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
1670 if (ucontrol->value.integer.value[2] != 0)
1671 cfg_data.sample_rate = ucontrol->value.integer.value[2];
1672 if (ucontrol->value.integer.value[4] != 0)
1673 cfg_data.copp_token = ucontrol->value.integer.value[4];
1674 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d copp_token %d\n",
1675 __func__, fe_id, session_type, be_id,
1676 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
1677 cfg_data.copp_token);
1678 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
1681 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
1687 static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
1688 struct snd_ctl_elem_value *ucontrol)
1690 u64 fe_id = kcontrol->private_value;
1691 int session_type = SESSION_TYPE_RX;
1693 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
1696 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
1699 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
1704 ucontrol->value.integer.value[0] = cfg_data.app_type;
1705 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
1706 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
1707 ucontrol->value.integer.value[3] = be_id;
1708 ucontrol->value.integer.value[4] = cfg_data.copp_token;
1709 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d copp_token %d\n",
1710 __func__, fe_id, session_type, be_id,
1711 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
1712 cfg_data.copp_token);
1717 static int msm_pcm_playback_pan_scale_ctl_info(struct snd_kcontrol *kcontrol,
1718 struct snd_ctl_elem_info *uinfo)
1720 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1721 uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
1725 static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol)
1731 struct snd_soc_component *usr_info = snd_kcontrol_chip(kcontrol);
1732 struct snd_soc_platform *platform;
1733 struct msm_plat_data *pdata;
1734 struct snd_pcm_substream *substream;
1735 struct msm_audio *prtd;
1736 struct asm_stream_pan_ctrl_params pan_param;
1737 char *usr_value = NULL;
1738 uint32_t *gain_ptr = NULL;
1741 pr_err("%s: usr_info is null\n", __func__);
1746 platform = snd_soc_component_to_platform(usr_info);
1748 pr_err("%s: platform is null\n", __func__);
1752 pdata = dev_get_drvdata(platform->dev);
1754 pr_err("%s: pdata is null\n", __func__);
1758 substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1760 pr_err("%s substream not found\n", __func__);
1765 if (!substream->runtime) {
1766 pr_err("%s substream runtime not found\n", __func__);
1770 prtd = substream->runtime->private_data;
1775 usr_value = (char *) ucontrol->value.bytes.data;
1777 pr_err("%s ucontrol data is null\n", __func__);
1781 memcpy(&pan_param.num_output_channels, &usr_value[len],
1782 sizeof(pan_param.num_output_channels));
1783 len += sizeof(pan_param.num_output_channels);
1784 if (pan_param.num_output_channels >
1785 PCM_FORMAT_MAX_NUM_CHANNEL) {
1789 memcpy(&pan_param.num_input_channels, &usr_value[len],
1790 sizeof(pan_param.num_input_channels));
1791 len += sizeof(pan_param.num_input_channels);
1792 if (pan_param.num_input_channels >
1793 PCM_FORMAT_MAX_NUM_CHANNEL) {
1798 if (usr_value[len++]) {
1799 memcpy(pan_param.output_channel_map, &usr_value[len],
1800 (pan_param.num_output_channels *
1801 sizeof(pan_param.output_channel_map[0])));
1802 len += (pan_param.num_output_channels *
1803 sizeof(pan_param.output_channel_map[0]));
1805 if (usr_value[len++]) {
1806 memcpy(pan_param.input_channel_map, &usr_value[len],
1807 (pan_param.num_input_channels *
1808 sizeof(pan_param.input_channel_map[0])));
1809 len += (pan_param.num_input_channels *
1810 sizeof(pan_param.input_channel_map[0]));
1812 if (usr_value[len++]) {
1813 gain_ptr = (uint32_t *) &usr_value[len];
1814 for (i = 0; i < pan_param.num_output_channels *
1815 pan_param.num_input_channels; i++) {
1817 !(gain_ptr[i] > 0) ?
1819 len += sizeof(pan_param.gain[i]);
1821 len += (pan_param.num_input_channels *
1822 pan_param.num_output_channels * sizeof(pan_param.gain[0]));
1825 ret = q6asm_set_mfc_panning_params(prtd->audio_client,
1827 len -= pan_param.num_output_channels *
1828 pan_param.num_input_channels * sizeof(pan_param.gain[0]);
1830 for (i = 0; i < pan_param.num_output_channels *
1831 pan_param.num_input_channels; i++) {
1833 * The data userspace passes is already in Q14 format.
1834 * For volume gain is in Q28.
1837 (gain_ptr[i]) << 14;
1838 len += sizeof(pan_param.gain[i]);
1841 ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
1848 static int msm_pcm_playback_pan_scale_ctl_get(struct snd_kcontrol *kcontrol,
1849 struct snd_ctl_elem_value *ucontrol)
1854 static int msm_add_stream_pan_scale_controls(struct snd_soc_pcm_runtime *rtd)
1856 const char *playback_mixer_ctl_name = "Audio Stream";
1857 const char *deviceNo = "NN";
1858 const char *suffix = "Pan Scale Control";
1859 char *mixer_str = NULL;
1862 struct msm_plat_data *pdata;
1863 struct snd_kcontrol_new pan_scale_control[1] = {
1865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1867 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1868 .info = msm_pcm_playback_pan_scale_ctl_info,
1869 .get = msm_pcm_playback_pan_scale_ctl_get,
1870 .put = msm_pcm_playback_pan_scale_ctl_put,
1876 pr_err("%s: NULL rtd\n", __func__);
1880 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
1881 strlen(deviceNo) + 1 + strlen(suffix) + 1;
1882 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1888 snprintf(mixer_str, ctl_len, "%s %d %s",
1889 playback_mixer_ctl_name, rtd->pcm->device, suffix);
1890 pan_scale_control[0].name = mixer_str;
1891 pan_scale_control[0].private_value = rtd->dai_link->be_id;
1892 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
1893 pdata = dev_get_drvdata(rtd->platform->dev);
1896 pdata->pcm = rtd->pcm;
1897 ret = snd_soc_add_platform_controls(rtd->platform,
1900 (pan_scale_control));
1902 pr_err("%s: failed add ctl %s. err = %d\n",
1903 __func__, mixer_str, ret);
1905 pr_err("%s: NULL pdata\n", __func__);
1915 static int msm_pcm_playback_dnmix_ctl_get(struct snd_kcontrol *kcontrol,
1916 struct snd_ctl_elem_value *ucontrol)
1921 static int msm_pcm_playback_dnmix_ctl_info(struct snd_kcontrol *kcontrol,
1922 struct snd_ctl_elem_info *uinfo)
1924 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1925 uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
1929 static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
1930 struct snd_ctl_elem_value *ucontrol)
1935 struct snd_soc_component *usr_info = snd_kcontrol_chip(kcontrol);
1936 struct snd_soc_platform *platform;
1937 struct msm_plat_data *pdata;
1938 struct snd_pcm_substream *substream;
1939 struct msm_audio *prtd;
1940 struct asm_stream_pan_ctrl_params dnmix_param;
1946 pr_err("%s usr_info is null\n", __func__);
1950 platform = snd_soc_component_to_platform(usr_info);
1952 pr_err("%s platform is null\n", __func__);
1956 pdata = dev_get_drvdata(platform->dev);
1958 pr_err("%s pdata is null\n", __func__);
1962 substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1964 pr_err("%s substream not found\n", __func__);
1968 if (!substream->runtime) {
1969 pr_err("%s substream runtime not found\n", __func__);
1973 prtd = substream->runtime->private_data;
1978 usr_value = (char *) ucontrol->value.bytes.data;
1980 pr_err("%s usrvalue is null\n", __func__);
1983 memcpy(&be_id, usr_value, sizeof(be_id));
1984 len += sizeof(be_id);
1985 stream_id = prtd->audio_client->session;
1986 memcpy(&dnmix_param.num_output_channels, &usr_value[len],
1987 sizeof(dnmix_param.num_output_channels));
1988 len += sizeof(dnmix_param.num_output_channels);
1989 if (dnmix_param.num_output_channels >
1990 PCM_FORMAT_MAX_NUM_CHANNEL) {
1994 memcpy(&dnmix_param.num_input_channels, &usr_value[len],
1995 sizeof(dnmix_param.num_input_channels));
1996 len += sizeof(dnmix_param.num_input_channels);
1997 if (dnmix_param.num_input_channels >
1998 PCM_FORMAT_MAX_NUM_CHANNEL) {
2002 if (usr_value[len++]) {
2003 memcpy(dnmix_param.output_channel_map, &usr_value[len],
2004 (dnmix_param.num_output_channels *
2005 sizeof(dnmix_param.output_channel_map[0])));
2006 len += (dnmix_param.num_output_channels *
2007 sizeof(dnmix_param.output_channel_map[0]));
2009 if (usr_value[len++]) {
2010 memcpy(dnmix_param.input_channel_map, &usr_value[len],
2011 (dnmix_param.num_input_channels *
2012 sizeof(dnmix_param.input_channel_map[0])));
2013 len += (dnmix_param.num_input_channels *
2014 sizeof(dnmix_param.input_channel_map[0]));
2016 if (usr_value[len++]) {
2017 memcpy(dnmix_param.gain, (uint32_t *) &usr_value[len],
2018 (dnmix_param.num_input_channels *
2019 dnmix_param.num_output_channels *
2020 sizeof(dnmix_param.gain[0])));
2021 len += (dnmix_param.num_input_channels *
2022 dnmix_param.num_output_channels * sizeof(dnmix_param.gain[0]));
2024 msm_routing_set_downmix_control_data(be_id,
2032 static int msm_add_device_down_mix_controls(struct snd_soc_pcm_runtime *rtd)
2034 const char *playback_mixer_ctl_name = "Audio Device";
2035 const char *deviceNo = "NN";
2036 const char *suffix = "Downmix Control";
2037 char *mixer_str = NULL;
2038 int ctl_len = 0, ret = 0;
2039 struct msm_plat_data *pdata;
2040 struct snd_kcontrol_new device_downmix_control[1] = {
2042 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2044 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2045 .info = msm_pcm_playback_dnmix_ctl_info,
2046 .get = msm_pcm_playback_dnmix_ctl_get,
2047 .put = msm_pcm_playback_dnmix_ctl_put,
2053 pr_err("%s NULL rtd\n", __func__);
2057 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2058 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2059 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2065 snprintf(mixer_str, ctl_len, "%s %d %s",
2066 playback_mixer_ctl_name, rtd->pcm->device, suffix);
2067 device_downmix_control[0].name = mixer_str;
2068 device_downmix_control[0].private_value = rtd->dai_link->be_id;
2069 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
2070 pdata = dev_get_drvdata(rtd->platform->dev);
2073 pdata->pcm = rtd->pcm;
2074 ret = snd_soc_add_platform_controls(rtd->platform,
2075 device_downmix_control,
2077 (device_downmix_control));
2079 pr_err("%s: failed add ctl %s. err = %d\n",
2080 __func__, mixer_str, ret);
2082 pr_err("%s: NULL pdata\n", __func__);
2090 static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
2091 struct snd_ctl_elem_value *ucontrol)
2093 u64 fe_id = kcontrol->private_value;
2094 int session_type = SESSION_TYPE_TX;
2095 int be_id = ucontrol->value.integer.value[3];
2096 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0};
2099 cfg_data.app_type = ucontrol->value.integer.value[0];
2100 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
2101 if (ucontrol->value.integer.value[2] != 0)
2102 cfg_data.sample_rate = ucontrol->value.integer.value[2];
2103 if (ucontrol->value.integer.value[4] != 0)
2104 cfg_data.copp_token = ucontrol->value.integer.value[4];
2105 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d copp_token %d\n",
2106 __func__, fe_id, session_type, be_id,
2107 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
2108 cfg_data.copp_token);
2109 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
2112 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
2118 static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
2119 struct snd_ctl_elem_value *ucontrol)
2121 u64 fe_id = kcontrol->private_value;
2122 int session_type = SESSION_TYPE_TX;
2124 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
2127 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
2130 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
2135 ucontrol->value.integer.value[0] = cfg_data.app_type;
2136 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
2137 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
2138 ucontrol->value.integer.value[3] = be_id;
2139 ucontrol->value.integer.value[4] = cfg_data.copp_token;
2140 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d copp_token %d\n",
2141 __func__, fe_id, session_type, be_id,
2142 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
2143 cfg_data.copp_token);
2148 static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
2150 struct snd_pcm *pcm = rtd->pcm;
2151 struct snd_pcm_usr *app_type_info;
2152 struct snd_kcontrol *kctl;
2153 const char *playback_mixer_ctl_name = "Audio Stream";
2154 const char *capture_mixer_ctl_name = "Audio Stream Capture";
2155 const char *deviceNo = "NN";
2156 const char *suffix = "App Type Cfg";
2157 int ctl_len, ret = 0;
2159 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
2160 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2161 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2162 pr_debug("%s: Playback app type cntrl add\n", __func__);
2163 ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
2164 NULL, 1, ctl_len, rtd->dai_link->be_id,
2167 pr_err("%s: playback app type cntrl add failed: %d\n",
2171 kctl = app_type_info->kctl;
2172 snprintf(kctl->id.name, ctl_len, "%s %d %s",
2173 playback_mixer_ctl_name, rtd->pcm->device, suffix);
2174 kctl->put = msm_pcm_playback_app_type_cfg_ctl_put;
2175 kctl->get = msm_pcm_playback_app_type_cfg_ctl_get;
2178 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
2179 ctl_len = strlen(capture_mixer_ctl_name) + 1 +
2180 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2181 pr_debug("%s: Capture app type cntrl add\n", __func__);
2182 ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
2183 NULL, 1, ctl_len, rtd->dai_link->be_id,
2186 pr_err("%s: capture app type cntrl add failed: %d\n",
2190 kctl = app_type_info->kctl;
2191 snprintf(kctl->id.name, ctl_len, "%s %d %s",
2192 capture_mixer_ctl_name, rtd->pcm->device, suffix);
2193 kctl->put = msm_pcm_capture_app_type_cfg_ctl_put;
2194 kctl->get = msm_pcm_capture_app_type_cfg_ctl_get;
2200 static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
2201 struct snd_ctl_elem_value *ucontrol)
2203 u64 fe_id = kcontrol->private_value & 0xFF;
2204 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2208 struct msm_audio *prtd = NULL;
2209 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2210 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2211 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2212 struct snd_pcm *pcm = NULL;
2213 struct snd_pcm_substream *substream = NULL;
2214 struct msm_pcm_channel_mixer *chmixer_pspd = NULL;
2216 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2217 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2221 if ((session_type != SESSION_TYPE_TX) &&
2222 (session_type != SESSION_TYPE_RX)) {
2223 pr_err("%s: invalid session type %d\n", __func__, session_type);
2227 pcm = pdata->pcm_device[fe_id];
2229 pr_err("%s invalid pcm handle for fe_id %llu\n",
2235 if (session_type == SESSION_TYPE_RX)
2236 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
2238 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2240 pr_err("%s substream not found\n", __func__);
2245 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2246 chmixer_pspd->enable = ucontrol->value.integer.value[0];
2247 chmixer_pspd->rule = ucontrol->value.integer.value[1];
2248 chmixer_pspd->input_channel = ucontrol->value.integer.value[2];
2249 chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
2250 chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
2252 /* cache value and take effect during adm_open stage */
2253 msm_pcm_routing_set_channel_mixer_cfg(fe_id,
2257 if (substream->runtime) {
2258 prtd = substream->runtime->private_data;
2260 pr_err("%s find invalid prtd fail\n", __func__);
2264 if (chmixer_pspd->enable) {
2265 stream_id = prtd->audio_client->session;
2266 be_id = chmixer_pspd->port_idx;
2267 msm_pcm_routing_set_channel_mixer_runtime(be_id,
2277 static int msm_pcm_channel_mixer_cfg_ctl_get(struct snd_kcontrol *kcontrol,
2278 struct snd_ctl_elem_value *ucontrol)
2280 u64 fe_id = kcontrol->private_value & 0xFF;
2281 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2282 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2283 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2284 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2285 struct msm_pcm_channel_mixer *chmixer_pspd;
2287 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2288 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2292 if ((session_type != SESSION_TYPE_TX) &&
2293 (session_type != SESSION_TYPE_RX)) {
2294 pr_err("%s: invalid session type %d\n", __func__, session_type);
2298 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2299 ucontrol->value.integer.value[0] = chmixer_pspd->enable;
2300 ucontrol->value.integer.value[1] = chmixer_pspd->rule;
2301 ucontrol->value.integer.value[2] = chmixer_pspd->input_channel;
2302 ucontrol->value.integer.value[3] = chmixer_pspd->output_channel;
2303 ucontrol->value.integer.value[4] = chmixer_pspd->port_idx;
2307 static int msm_pcm_channel_mixer_output_map_ctl_put(
2308 struct snd_kcontrol *kcontrol,
2309 struct snd_ctl_elem_value *ucontrol)
2311 u64 fe_id = kcontrol->private_value & 0xFF;
2312 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2314 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2315 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2316 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2317 struct msm_pcm_channel_mixer *chmixer_pspd;
2319 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2320 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2324 if ((session_type != SESSION_TYPE_TX) &&
2325 (session_type != SESSION_TYPE_RX)) {
2326 pr_err("%s: invalid session type %d\n", __func__, session_type);
2330 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2331 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2332 chmixer_pspd->out_ch_map[i] =
2333 ucontrol->value.integer.value[i];
2338 static int msm_pcm_channel_mixer_output_map_ctl_get(
2339 struct snd_kcontrol *kcontrol,
2340 struct snd_ctl_elem_value *ucontrol)
2342 u64 fe_id = kcontrol->private_value & 0xFF;
2343 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2345 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2346 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2347 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2348 struct msm_pcm_channel_mixer *chmixer_pspd;
2350 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2351 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2355 if ((session_type != SESSION_TYPE_TX) &&
2356 (session_type != SESSION_TYPE_RX)) {
2357 pr_err("%s: invalid session type %d\n", __func__, session_type);
2361 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2362 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2363 ucontrol->value.integer.value[i] =
2364 chmixer_pspd->out_ch_map[i];
2368 static int msm_pcm_channel_mixer_input_map_ctl_put(
2369 struct snd_kcontrol *kcontrol,
2370 struct snd_ctl_elem_value *ucontrol)
2372 u64 fe_id = kcontrol->private_value & 0xFF;
2373 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2375 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2376 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2377 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2378 struct msm_pcm_channel_mixer *chmixer_pspd;
2380 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2381 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2385 if ((session_type != SESSION_TYPE_TX) &&
2386 (session_type != SESSION_TYPE_RX)) {
2387 pr_err("%s: invalid session type %d\n", __func__, session_type);
2391 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2392 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2393 chmixer_pspd->in_ch_map[i] = ucontrol->value.integer.value[i];
2398 static int msm_pcm_channel_mixer_input_map_ctl_get(
2399 struct snd_kcontrol *kcontrol,
2400 struct snd_ctl_elem_value *ucontrol)
2402 u64 fe_id = kcontrol->private_value & 0xFF;
2403 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2405 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2406 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2407 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2408 struct msm_pcm_channel_mixer *chmixer_pspd;
2410 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2411 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2415 if ((session_type != SESSION_TYPE_TX) &&
2416 (session_type != SESSION_TYPE_RX)) {
2417 pr_err("%s: invalid session type %d\n", __func__, session_type);
2421 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2422 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2423 ucontrol->value.integer.value[i] =
2424 chmixer_pspd->in_ch_map[i];
2428 static int msm_pcm_channel_mixer_weight_ctl_put(
2429 struct snd_kcontrol *kcontrol,
2430 struct snd_ctl_elem_value *ucontrol)
2432 u64 fe_id = kcontrol->private_value & 0xFF;
2433 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2434 int channel = (kcontrol->private_value >> 16) & 0xFF;
2436 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2437 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2438 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2439 struct msm_pcm_channel_mixer *chmixer_pspd;
2441 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2442 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2446 if ((session_type != SESSION_TYPE_TX) &&
2447 (session_type != SESSION_TYPE_RX)) {
2448 pr_err("%s: invalid session type %d\n", __func__, session_type);
2452 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2453 if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V2) {
2454 pr_err("%s: invalid channel number %d\n", __func__, channel);
2459 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2460 chmixer_pspd->channel_weight[channel][i] =
2461 ucontrol->value.integer.value[i];
2465 static int msm_pcm_channel_mixer_weight_ctl_get(
2466 struct snd_kcontrol *kcontrol,
2467 struct snd_ctl_elem_value *ucontrol)
2469 u64 fe_id = kcontrol->private_value & 0xFF;
2470 int session_type = (kcontrol->private_value >> 8) & 0xFF;
2471 int channel = (kcontrol->private_value >> 16) & 0xFF;
2472 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
2473 struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
2474 struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
2476 struct msm_pcm_channel_mixer *chmixer_pspd;
2478 if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2479 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2483 if ((session_type != SESSION_TYPE_TX) &&
2484 (session_type != SESSION_TYPE_RX)) {
2485 pr_err("%s: invalid session type %d\n", __func__, session_type);
2489 if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V2) {
2490 pr_err("%s: invalid channel number %d\n", __func__, channel);
2495 chmixer_pspd = &(pdata->chmixer_pspd[fe_id][session_type]);
2496 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2497 ucontrol->value.integer.value[i] =
2498 chmixer_pspd->channel_weight[channel][i];
2502 static int msm_pcm_channel_mixer_output_map_info(struct snd_kcontrol *kcontrol,
2503 struct snd_ctl_elem_info *uinfo)
2505 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2506 uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V2;
2507 uinfo->value.integer.min = 1;
2508 uinfo->value.integer.max = 64;
2512 static int msm_pcm_add_channel_mixer_output_map_controls(
2513 struct snd_soc_pcm_runtime *rtd)
2515 struct snd_pcm *pcm = rtd->pcm;
2516 const char *playback_mixer_ctl_name = "AudStr";
2517 const char *capture_mixer_ctl_name = "AudStr Capture";
2518 const char *deviceNo = "NN";
2519 const char *suffix = "ChMixer Output Map";
2521 int session_type = 0;
2522 char *playback_mixer_str = NULL;
2523 char *capture_mixer_str = NULL;
2525 struct snd_kcontrol_new channel_mixer_output_map_control[2] = {
2527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2529 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2530 .info = msm_pcm_channel_mixer_output_map_info,
2531 .put = msm_pcm_channel_mixer_output_map_ctl_put,
2532 .get = msm_pcm_channel_mixer_output_map_ctl_get,
2536 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2538 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2539 .info = msm_pcm_channel_mixer_output_map_info,
2540 .put = msm_pcm_channel_mixer_output_map_ctl_put,
2541 .get = msm_pcm_channel_mixer_output_map_ctl_get,
2546 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) {
2547 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2548 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2549 playback_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2550 if (playback_mixer_str == NULL) {
2551 pr_err("failed to allocate mixer ctrl str of len %d",
2555 session_type = SESSION_TYPE_RX;
2556 snprintf(playback_mixer_str, ctl_len, "%s %d %s",
2557 playback_mixer_ctl_name, rtd->pcm->device, suffix);
2558 channel_mixer_output_map_control[0].name = playback_mixer_str;
2559 channel_mixer_output_map_control[0].private_value =
2560 (rtd->dai_link->be_id) | (session_type << 8);
2561 ret = snd_soc_add_platform_controls(rtd->platform,
2562 &channel_mixer_output_map_control[0],
2565 pr_err("%s: failed add platform ctl, err = %d\n",
2572 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) {
2573 ctl_len = strlen(capture_mixer_ctl_name) + 1 +
2574 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2575 capture_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2576 if (capture_mixer_str == NULL) {
2577 pr_err("failed to allocate mixer ctrl str of len %d",
2581 session_type = SESSION_TYPE_TX;
2582 snprintf(capture_mixer_str, ctl_len, "%s %d %s",
2583 capture_mixer_ctl_name, rtd->pcm->device, suffix);
2584 channel_mixer_output_map_control[1].name = capture_mixer_str;
2585 channel_mixer_output_map_control[1].private_value =
2586 (rtd->dai_link->be_id) | (session_type << 8);
2587 ret = snd_soc_add_platform_controls(rtd->platform,
2588 &channel_mixer_output_map_control[1],
2591 pr_err("%s: failed add platform ctl, err = %d\n",
2599 kfree(playback_mixer_str);
2600 kfree(capture_mixer_str);
2604 static int msm_pcm_channel_mixer_input_map_info(struct snd_kcontrol *kcontrol,
2605 struct snd_ctl_elem_info *uinfo)
2607 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2608 uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V2;
2609 uinfo->value.integer.min = 1;
2610 uinfo->value.integer.max = 64;
2614 static int msm_pcm_add_channel_mixer_input_map_controls(
2615 struct snd_soc_pcm_runtime *rtd)
2617 struct snd_pcm *pcm = rtd->pcm;
2618 const char *playback_mixer_ctl_name = "AudStr";
2619 const char *capture_mixer_ctl_name = "AudStr Capture";
2620 const char *deviceNo = "NN";
2621 const char *suffix = "ChMixer Input Map";
2623 int session_type = 0;
2624 char *playback_mixer_str = NULL;
2625 char *capture_mixer_str = NULL;
2627 struct snd_kcontrol_new channel_mixer_input_map_control[2] = {
2629 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2632 .info = msm_pcm_channel_mixer_input_map_info,
2633 .put = msm_pcm_channel_mixer_input_map_ctl_put,
2634 .get = msm_pcm_channel_mixer_input_map_ctl_get,
2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2640 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2641 .info = msm_pcm_channel_mixer_input_map_info,
2642 .put = msm_pcm_channel_mixer_input_map_ctl_put,
2643 .get = msm_pcm_channel_mixer_input_map_ctl_get,
2648 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) {
2649 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2650 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2651 playback_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2652 if (playback_mixer_str == NULL) {
2653 pr_err("failed to allocate mixer ctrl str of len %d",
2657 session_type = SESSION_TYPE_RX;
2658 snprintf(playback_mixer_str, ctl_len, "%s %d %s",
2659 playback_mixer_ctl_name, rtd->pcm->device, suffix);
2660 channel_mixer_input_map_control[0].name = playback_mixer_str;
2661 channel_mixer_input_map_control[0].private_value =
2662 (rtd->dai_link->be_id) | (session_type << 8);
2663 ret = snd_soc_add_platform_controls(rtd->platform,
2664 &channel_mixer_input_map_control[0],
2667 pr_err("%s: failed add platform ctl, err = %d\n",
2674 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) {
2675 ctl_len = strlen(capture_mixer_ctl_name) + 1 +
2676 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2677 capture_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2678 if (capture_mixer_str == NULL) {
2679 pr_err("failed to allocate mixer ctrl str of len %d",
2683 session_type = SESSION_TYPE_TX;
2684 snprintf(capture_mixer_str, ctl_len, "%s %d %s",
2685 capture_mixer_ctl_name, rtd->pcm->device, suffix);
2686 channel_mixer_input_map_control[1].name = capture_mixer_str;
2687 channel_mixer_input_map_control[1].private_value =
2688 (rtd->dai_link->be_id) | (session_type << 8);
2689 ret = snd_soc_add_platform_controls(rtd->platform,
2690 &channel_mixer_input_map_control[1],
2693 pr_err("%s: failed add platform ctl, err = %d\n",
2701 kfree(playback_mixer_str);
2702 kfree(capture_mixer_str);
2706 static int msm_pcm_channel_mixer_cfg_info(struct snd_kcontrol *kcontrol,
2707 struct snd_ctl_elem_info *uinfo)
2709 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2711 uinfo->value.integer.min = 0;
2712 uinfo->value.integer.max = 0xFFFFFFFF;
2716 static int msm_pcm_add_channel_mixer_cfg_controls(
2717 struct snd_soc_pcm_runtime *rtd)
2719 struct snd_pcm *pcm = rtd->pcm;
2720 const char *playback_mixer_ctl_name = "AudStr";
2721 const char *capture_mixer_ctl_name = "AudStr Capture";
2722 const char *deviceNo = "NN";
2723 const char *suffix = "ChMixer Cfg";
2725 char *playback_mixer_str = NULL;
2726 char *capture_mixer_str = NULL;
2727 int session_type = 0;
2729 struct msm_plat_data *pdata = NULL;
2730 struct snd_kcontrol_new channel_mixer_cfg_control[2] = {
2732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2734 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2735 .info = msm_pcm_channel_mixer_cfg_info,
2736 .put = msm_pcm_channel_mixer_cfg_ctl_put,
2737 .get = msm_pcm_channel_mixer_cfg_ctl_get,
2741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2743 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2744 .info = msm_pcm_channel_mixer_cfg_info,
2745 .put = msm_pcm_channel_mixer_cfg_ctl_put,
2746 .get = msm_pcm_channel_mixer_cfg_ctl_get,
2751 pdata = (struct msm_plat_data *)
2752 dev_get_drvdata(rtd->platform->dev);
2753 if (pdata == NULL) {
2754 pr_err("%s: platform data not populated\n", __func__);
2759 pdata->pcm_device[rtd->dai_link->be_id] = rtd->pcm;
2761 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) {
2762 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2763 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2764 playback_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2765 if (playback_mixer_str == NULL) {
2766 pr_err("failed to allocate mixer ctrl str of len %d",
2770 session_type = SESSION_TYPE_RX;
2771 snprintf(playback_mixer_str, ctl_len, "%s %d %s",
2772 playback_mixer_ctl_name, rtd->pcm->device, suffix);
2773 channel_mixer_cfg_control[0].name = playback_mixer_str;
2774 channel_mixer_cfg_control[0].private_value =
2775 (rtd->dai_link->be_id) | (session_type << 8);
2776 ret = snd_soc_add_platform_controls(rtd->platform,
2777 &channel_mixer_cfg_control[0],
2780 pr_err("%s: failed add platform ctl, err = %d\n",
2787 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) {
2788 ctl_len = strlen(capture_mixer_ctl_name) + 1 +
2789 strlen(deviceNo) + 1 + strlen(suffix) + 1;
2790 capture_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2791 if (capture_mixer_str == NULL) {
2792 pr_err("failed to allocate mixer ctrl str of len %d",
2796 session_type = SESSION_TYPE_TX;
2797 snprintf(capture_mixer_str, ctl_len, "%s %d %s",
2798 capture_mixer_ctl_name, rtd->pcm->device, suffix);
2799 channel_mixer_cfg_control[1].name = capture_mixer_str;
2800 channel_mixer_cfg_control[1].private_value =
2801 (rtd->dai_link->be_id) | (session_type << 8);
2802 ret = snd_soc_add_platform_controls(rtd->platform,
2803 &channel_mixer_cfg_control[1],
2806 pr_err("%s: failed add platform ctl, err = %d\n",
2814 kfree(playback_mixer_str);
2815 kfree(capture_mixer_str);
2819 static int msm_pcm_channel_mixer_weight_info(struct snd_kcontrol *kcontrol,
2820 struct snd_ctl_elem_info *uinfo)
2822 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2823 uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V2;
2824 uinfo->value.integer.min = 0;
2825 uinfo->value.integer.max = 0x4000;
2829 static int msm_pcm_add_channel_mixer_weight_controls(
2830 struct snd_soc_pcm_runtime *rtd,
2833 struct snd_pcm *pcm = rtd->pcm;
2834 const char *playback_mixer_ctl_name = "AudStr";
2835 const char *capture_mixer_ctl_name = "AudStr Capture";
2836 const char *deviceNo = "NN";
2837 const char *channelNo = "NN";
2838 const char *suffix = "ChMixer Weight Ch";
2840 int session_type = 0;
2841 char *playback_mixer_str = NULL;
2842 char *capture_mixer_str = NULL;
2844 struct snd_kcontrol_new channel_mixer_weight_control[2] = {
2846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2848 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2849 .info = msm_pcm_channel_mixer_weight_info,
2850 .put = msm_pcm_channel_mixer_weight_ctl_put,
2851 .get = msm_pcm_channel_mixer_weight_ctl_get,
2855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2857 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2858 .info = msm_pcm_channel_mixer_weight_info,
2859 .put = msm_pcm_channel_mixer_weight_ctl_put,
2860 .get = msm_pcm_channel_mixer_weight_ctl_get,
2865 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) {
2866 ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2867 strlen(deviceNo) + 1 + strlen(suffix) + 1 +
2868 strlen(channelNo) + 1;
2869 playback_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2870 if (playback_mixer_str == NULL) {
2871 pr_err("failed to allocate mixer ctrl str of len %d",
2875 session_type = SESSION_TYPE_RX;
2876 snprintf(playback_mixer_str, ctl_len, "%s %d %s %d",
2877 playback_mixer_ctl_name, rtd->pcm->device, suffix,
2879 channel_mixer_weight_control[0].name = playback_mixer_str;
2880 channel_mixer_weight_control[0].private_value =
2881 (rtd->dai_link->be_id) | (session_type << 8)
2883 ret = snd_soc_add_platform_controls(rtd->platform,
2884 &channel_mixer_weight_control[0],
2887 pr_err("%s: failed add platform ctl, err = %d\n",
2894 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) {
2895 ctl_len = strlen(capture_mixer_ctl_name) + 1 +
2896 strlen(deviceNo) + 1 + strlen(suffix) + 1 +
2897 strlen(channelNo) + 1;
2898 capture_mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2899 if (capture_mixer_str == NULL) {
2900 pr_err("failed to allocate mixer ctrl str of len %d",
2904 session_type = SESSION_TYPE_TX;
2905 snprintf(capture_mixer_str, ctl_len, "%s %d %s %d",
2906 capture_mixer_ctl_name, rtd->pcm->device, suffix,
2908 channel_mixer_weight_control[1].name = capture_mixer_str;
2909 channel_mixer_weight_control[1].private_value =
2910 (rtd->dai_link->be_id) | (session_type << 8)
2912 ret = snd_soc_add_platform_controls(rtd->platform,
2913 &channel_mixer_weight_control[1],
2916 pr_err("%s: failed add platform ctl, err = %d\n",
2924 kfree(playback_mixer_str);
2925 kfree(capture_mixer_str);
2929 static int msm_pcm_add_channel_mixer_controls(struct snd_soc_pcm_runtime *rtd)
2933 ret = msm_pcm_add_channel_mixer_cfg_controls(rtd);
2935 pr_err("%s: pcm add channel mixer cfg controls failed:%d\n",
2937 ret = msm_pcm_add_channel_mixer_input_map_controls(rtd);
2939 pr_err("%s: pcm add channel mixer input map controls failed:%d\n",
2941 ret = msm_pcm_add_channel_mixer_output_map_controls(rtd);
2943 pr_err("%s: pcm add channel mixer output map controls failed:%d\n",
2946 for (i = 1; i <= PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2947 ret |= msm_pcm_add_channel_mixer_weight_controls(rtd, i);
2949 pr_err("%s: pcm add channel mixer weight controls failed:%d\n",
2954 static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
2958 pr_debug("%s\n", __func__);
2959 ret = msm_pcm_add_chmap_controls(rtd);
2961 pr_err("%s: pcm add controls failed:%d\n", __func__, ret);
2962 ret = msm_pcm_add_app_type_controls(rtd);
2964 pr_err("%s: pcm add app type controls failed:%d\n",
2966 ret = msm_add_stream_pan_scale_controls(rtd);
2968 pr_err("%s: pcm add pan scale controls failed:%d\n",
2970 ret = msm_add_device_down_mix_controls(rtd);
2972 pr_err("%s: pcm add dnmix controls failed:%d\n",
2974 ret = msm_pcm_add_channel_mixer_controls(rtd);
2976 pr_err("%s: pcm add channel mixer controls failed:%d\n",
2981 static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
2983 struct snd_card *card = rtd->card->snd_card;
2986 if (!card->dev->coherent_dma_mask)
2987 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
2989 ret = msm_pcm_add_controls(rtd);
2991 pr_err("%s, kctl add failed:%d\n", __func__, ret);
2995 ret = msm_pcm_add_volume_control(rtd);
2997 pr_err("%s: Could not add pcm Volume Control %d\n",
3000 ret = msm_pcm_add_compress_control(rtd);
3002 pr_err("%s: Could not add pcm Compress Control %d\n",
3005 ret = msm_pcm_add_audio_adsp_stream_cmd_control(rtd);
3007 pr_err("%s: Could not add pcm ADSP Stream Cmd Control\n",
3010 ret = msm_pcm_add_audio_adsp_stream_callback_control(rtd);
3012 pr_err("%s: Could not add pcm ADSP Stream Callback Control\n",
3018 static snd_pcm_sframes_t msm_pcm_delay_blk(struct snd_pcm_substream *substream,
3019 struct snd_soc_dai *dai)
3021 struct snd_pcm_runtime *runtime = substream->runtime;
3022 struct msm_audio *prtd = runtime->private_data;
3023 struct audio_client *ac = prtd->audio_client;
3024 snd_pcm_sframes_t frames;
3027 ret = q6asm_get_path_delay(prtd->audio_client);
3029 pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret);
3033 /* convert microseconds to frames */
3034 frames = ac->path_delay / 1000 * runtime->rate / 1000;
3036 /* also convert the remainder from the initial division */
3037 frames += ac->path_delay % 1000 * runtime->rate / 1000000;
3039 /* overcompensate for the loss of precision (empirical) */
3045 static struct snd_soc_platform_driver msm_soc_platform = {
3046 .ops = &msm_pcm_ops,
3047 .pcm_new = msm_asoc_pcm_new,
3048 .delay_blk = msm_pcm_delay_blk,
3051 static int msm_pcm_probe(struct platform_device *pdev)
3055 struct msm_plat_data *pdata;
3056 const char *latency_level;
3058 rc = of_property_read_u32(pdev->dev.of_node,
3059 "qcom,msm-pcm-dsp-id", &id);
3061 dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n",
3066 pdata = kzalloc(sizeof(struct msm_plat_data), GFP_KERNEL);
3068 dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
3072 if (of_property_read_bool(pdev->dev.of_node,
3073 "qcom,msm-pcm-low-latency")) {
3075 pdata->perf_mode = LOW_LATENCY_PCM_MODE;
3076 rc = of_property_read_string(pdev->dev.of_node,
3077 "qcom,latency-level", &latency_level);
3079 if (!strcmp(latency_level, "ultra"))
3080 pdata->perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
3081 else if (!strcmp(latency_level, "ull-pp"))
3083 ULL_POST_PROCESSING_PCM_MODE;
3086 pdata->perf_mode = LEGACY_PCM_MODE;
3089 if (of_property_read_bool(pdev->dev.of_node,
3090 "qcom,avs-version"))
3091 pdata->avs_ver = true;
3093 pdata->avs_ver = false;
3095 pr_debug("%s: avs_ver = %d\n", __func__, pdata->avs_ver);
3097 dev_set_drvdata(&pdev->dev, pdata);
3099 dev_dbg(&pdev->dev, "%s: dev name %s\n",
3100 __func__, dev_name(&pdev->dev));
3101 return snd_soc_register_platform(&pdev->dev,
3105 static int msm_pcm_remove(struct platform_device *pdev)
3107 struct msm_plat_data *pdata;
3109 pdata = dev_get_drvdata(&pdev->dev);
3111 snd_soc_unregister_platform(&pdev->dev);
3114 static const struct of_device_id msm_pcm_dt_match[] = {
3115 {.compatible = "qcom,msm-pcm-dsp"},
3118 MODULE_DEVICE_TABLE(of, msm_pcm_dt_match);
3120 static struct platform_driver msm_pcm_driver = {
3122 .name = "msm-pcm-dsp",
3123 .owner = THIS_MODULE,
3124 .of_match_table = msm_pcm_dt_match,
3126 .probe = msm_pcm_probe,
3127 .remove = msm_pcm_remove,
3130 static int __init msm_soc_platform_init(void)
3132 init_waitqueue_head(&the_locks.enable_wait);
3133 init_waitqueue_head(&the_locks.eos_wait);
3134 init_waitqueue_head(&the_locks.write_wait);
3135 init_waitqueue_head(&the_locks.read_wait);
3137 return platform_driver_register(&msm_pcm_driver);
3139 module_init(msm_soc_platform_init);
3141 static void __exit msm_soc_platform_exit(void)
3143 platform_driver_unregister(&msm_pcm_driver);
3145 module_exit(msm_soc_platform_exit);
3147 MODULE_DESCRIPTION("PCM module platform driver");
3148 MODULE_LICENSE("GPL v2");