OSDN Git Service

ASoC: msm: q6dspv2: vote for Glink Rx thread priority upgrade
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / sound / soc / msm / qdsp6v2 / msm-pcm-q6-v2.c
1 /* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
2  *
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.
6  *
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.
11  */
12
13
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>
30 #include <asm/dma.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/msm_audio_ion.h>
33 #include <linux/msm_audio.h>
34
35 #include <linux/of_device.h>
36 #include <sound/tlv.h>
37 #include <sound/pcm_params.h>
38 #include <sound/q6core.h>
39
40 #include "msm-pcm-q6-v2.h"
41 #include "msm-pcm-routing-v2.h"
42 #include "msm-qti-pp-config.h"
43
44 enum stream_state {
45         IDLE = 0,
46         STOPPED,
47         RUNNING,
48 };
49
50 static struct audio_locks the_locks;
51
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);
55
56
57 struct snd_msm {
58         struct snd_card *card;
59         struct snd_pcm *pcm;
60 };
61
62 #define CMD_EOS_MIN_TIMEOUT_LENGTH  50
63 #define CMD_EOS_TIMEOUT_MULTIPLIER  (HZ * 50)
64 #define MAX_PB_COPY_RETRIES         3
65
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,
77         .rate_min =             8000,
78         .rate_max =             384000,
79         .channels_min =         1,
80         .channels_max =         4,
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,
87         .fifo_size =            0,
88 };
89
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,
101         .rate_min =             8000,
102         .rate_max =             384000,
103         .channels_min =         1,
104         .channels_max =         8,
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,
111         .fifo_size =            0,
112 };
113
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
118 };
119
120 static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
121         .count = ARRAY_SIZE(supported_sample_rates),
122         .list = supported_sample_rates,
123         .mask = 0,
124 };
125
126 static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
127                                         void *priv_data)
128 {
129         struct msm_audio *prtd = priv_data;
130
131         BUG_ON(!prtd);
132
133         pr_debug("%s: event %x\n", __func__, event);
134
135         switch (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);
140         default:
141                 break;
142         }
143 }
144
145 static void event_handler(uint32_t opcode,
146                 uint32_t token, uint32_t *payload, void *priv)
147 {
148         struct msm_audio *prtd = priv;
149         struct snd_pcm_substream *substream = prtd->substream;
150         uint32_t *ptrmem = (uint32_t *)payload;
151         uint32_t idx = 0;
152         uint32_t size = 0;
153         uint8_t buf_index;
154         struct snd_soc_pcm_runtime *rtd;
155         int ret = 0;
156
157         switch (opcode) {
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))
167                         break;
168                 if (!prtd->mmap_flag || prtd->reset_event)
169                         break;
170                 if (q6asm_is_cpu_buf_avail_nolock(IN,
171                                 prtd->audio_client,
172                                 &size, &idx)) {
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);
177                 }
178                 break;
179         }
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);
184                 break;
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);
191                         return;
192                 }
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) {
199                         prtd->pcm_irq_pos +=
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,
209                                 prtd->audio_client,
210                                 &size, &idx) &&
211                             (substream->runtime->status->state ==
212                              SNDRV_PCM_STATE_RUNNING))
213                                 q6asm_read_nolock(prtd->audio_client);
214                 } else {
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,
220                                     prtd->audio_client,
221                                     &size, &idx) &&
222                                     (substream->runtime->status->state ==
223                                     SNDRV_PCM_STATE_RUNNING))
224                                         q6asm_read_nolock(prtd->audio_client);
225                         } else {
226                                 atomic_inc(&prtd->in_count);
227                         }
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);
233                         }
234                 }
235                 break;
236         }
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);
240                 if (!substream) {
241                         pr_err("%s: substream is NULL.\n", __func__);
242                         return;
243                 }
244
245                 rtd = substream->private_data;
246                 if (!rtd) {
247                         pr_err("%s: rtd is NULL\n", __func__);
248                         return;
249                 }
250
251                 ret = msm_adsp_inform_mixer_ctl(rtd, payload);
252                 if (ret) {
253                         pr_err("%s: failed to inform mixer ctl. err = %d\n",
254                                 __func__, ret);
255                         return;
256                 }
257
258                 break;
259         }
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);
266                                 break;
267                         }
268                         if (prtd->mmap_flag) {
269                                 pr_debug("%s:writing %d bytes of buffer to dsp\n",
270                                         __func__,
271                                         prtd->pcm_count);
272                                 q6asm_write_nolock(prtd->audio_client,
273                                         prtd->pcm_count,
274                                         0, 0, NO_TIMESTAMP);
275                         } else {
276                                 while (atomic_read(&prtd->out_needed)) {
277                                         pr_debug("%s:writing %d bytes of buffer to dsp\n",
278                                                 __func__,
279                                                 prtd->pcm_count);
280                                         q6asm_write_nolock(prtd->audio_client,
281                                                 prtd->pcm_count,
282                                                 0, 0, NO_TIMESTAMP);
283                                         atomic_dec(&prtd->out_needed);
284                                         wake_up(&the_locks.write_wait);
285                                 };
286                         }
287                         atomic_set(&prtd->start, 1);
288                         break;
289                 case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
290                         pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:",
291                                 __func__);
292                         break;
293                 default:
294                         pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
295                                 __func__, payload[0], payload[1]);
296                         break;
297                 }
298         }
299         break;
300         case RESET_EVENTS:
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);
311                 break;
312         default:
313                 pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
314                 break;
315         }
316 }
317
318 static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
319 {
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;
325         int ret;
326         uint32_t fmt_type = FORMAT_LINEAR_PCM;
327         uint16_t bits_per_sample;
328         uint16_t sample_word_size;
329
330         pdata = (struct msm_plat_data *)
331                 dev_get_drvdata(soc_prtd->platform->dev);
332         if (!pdata) {
333                 pr_err("%s: platform data not populated\n", __func__);
334                 return -EINVAL;
335         }
336         if (!prtd || !prtd->audio_client) {
337                 pr_err("%s: private data null or audio client freed\n",
338                         __func__);
339                 return -EINVAL;
340         }
341         params = &soc_prtd->dpcm[substream->stream].hw_params;
342
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;
350         if (prtd->enabled)
351                 return 0;
352
353         prtd->audio_client->perf_mode = pdata->perf_mode;
354         pr_debug("%s: perf: %x\n", __func__, pdata->perf_mode);
355
356         switch (params_format(params)) {
357         case SNDRV_PCM_FORMAT_S32_LE:
358                 bits_per_sample = 32;
359                 sample_word_size = 32;
360                 break;
361         case SNDRV_PCM_FORMAT_S24_LE:
362                 bits_per_sample = 24;
363                 sample_word_size = 32;
364                 break;
365         case SNDRV_PCM_FORMAT_S24_3LE:
366                 bits_per_sample = 24;
367                 sample_word_size = 24;
368                 break;
369         case SNDRV_PCM_FORMAT_S16_LE:
370         default:
371                 bits_per_sample = 16;
372                 sample_word_size = 16;
373                 break;
374         }
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);
380                 if (ret < 0) {
381                         pr_err("%s: q6asm_open_write_compressed failed (%d)\n",
382                         __func__, ret);
383                         q6asm_audio_client_free(prtd->audio_client);
384                         prtd->audio_client = NULL;
385                         return -ENOMEM;
386                 }
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);
391                 if (ret < 0) {
392                         pr_err("%s: q6asm_open_write_v3 failed (%d)\n",
393                         __func__, ret);
394                         q6asm_audio_client_free(prtd->audio_client);
395                         prtd->audio_client = NULL;
396                         return -ENOMEM;
397                 }
398         } else {
399                 ret = q6asm_open_write_with_retry(prtd->audio_client,
400                                 fmt_type, bits_per_sample);
401                 if (ret < 0) {
402                         pr_err("%s: q6asm_open_write_with_retry failed (%d)\n",
403                         __func__, ret);
404                         q6asm_audio_client_free(prtd->audio_client);
405                         prtd->audio_client = NULL;
406                         return -ENOMEM;
407                 }
408
409                 ret = q6asm_send_cal(prtd->audio_client);
410                 if (ret < 0)
411                         pr_debug("%s : Send cal failed : %d", __func__, ret);
412         }
413         pr_debug("%s: session ID %d\n", __func__,
414                         prtd->audio_client->session);
415         prtd->session_id = prtd->audio_client->session;
416
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,
421                                 prtd->session_id,
422                                 SNDRV_PCM_STREAM_PLAYBACK,
423                                 COMPRESSED_PASSTHROUGH_GEN);
424         } else {
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);
428         }
429         if (ret) {
430                 pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
431                 return ret;
432         }
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);
438         } else {
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,
446                                 DEFAULT_QF);
447                 else if (pdata->avs_ver &&
448                                 (q6core_get_avs_version() ==
449                                         Q6_SUBSYS_AVS2_7))
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,
454                                 sample_word_size);
455                 else
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,
461                                 DEFAULT_QF);
462         }
463         if (ret < 0)
464                 pr_info("%s: CMD Format block failed\n", __func__);
465
466         atomic_set(&prtd->out_count, runtime->periods);
467
468         prtd->enabled = 1;
469         prtd->cmd_pending = 0;
470         prtd->cmd_interrupt = 0;
471
472         return 0;
473 }
474
475 static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
476 {
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;
483         int ret = 0;
484         int i = 0;
485         uint16_t bits_per_sample = 16;
486         uint16_t sample_word_size;
487
488         pdata = (struct msm_plat_data *)
489                 dev_get_drvdata(soc_prtd->platform->dev);
490         if (!pdata) {
491                 pr_err("%s: platform data not populated\n", __func__);
492                 return -EINVAL;
493         }
494         if (!prtd || !prtd->audio_client) {
495                 pr_err("%s: private data null or audio client freed\n",
496                         __func__);
497                 return -EINVAL;
498         }
499
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;
509
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;
513                 else
514                         prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE;
515
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,
522                                         FORMAT_LINEAR_PCM,
523                                         bits_per_sample);
524                 else
525                         ret = q6asm_open_read_with_retry(prtd->audio_client,
526                                         FORMAT_LINEAR_PCM,
527                                         bits_per_sample, false);
528                 if (ret < 0) {
529                         pr_err("%s: q6asm_open_read failed\n", __func__);
530                         q6asm_audio_client_free(prtd->audio_client);
531                         prtd->audio_client = NULL;
532                         return -ENOMEM;
533                 }
534
535                 ret = q6asm_send_cal(prtd->audio_client);
536                 if (ret < 0)
537                         pr_debug("%s : Send cal failed : %d", __func__, ret);
538
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,
548                                 event);
549                 if (ret) {
550                         pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
551                         return ret;
552                 }
553         }
554
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;
561
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;
566         }
567
568         if (prtd->enabled != IDLE)
569                 return 0;
570
571         switch (runtime->format) {
572         case SNDRV_PCM_FORMAT_S32_LE:
573                 bits_per_sample = 32;
574                 sample_word_size = 32;
575                 break;
576         case SNDRV_PCM_FORMAT_S24_LE:
577                 bits_per_sample = 24;
578                 sample_word_size = 32;
579                 break;
580         case SNDRV_PCM_FORMAT_S24_3LE:
581                 bits_per_sample = 24;
582                 sample_word_size = 24;
583                 break;
584         case SNDRV_PCM_FORMAT_S16_LE:
585         default:
586                 bits_per_sample = 16;
587                 sample_word_size = 16;
588                 break;
589         }
590
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(
597                                         prtd->audio_client,
598                                         prtd->samp_rate,
599                                         prtd->channel_mode,
600                                         bits_per_sample,
601                                         sample_word_size,
602                                         ASM_LITTLE_ENDIAN,
603                                         DEFAULT_QF);
604         else if (pdata->avs_ver &&
605                         (q6core_get_avs_version() ==
606                                 Q6_SUBSYS_AVS2_7))
607                 ret = q6asm_enc_cfg_blk_pcm_format_support_v3(
608                                         prtd->audio_client,
609                                         prtd->samp_rate,
610                                         prtd->channel_mode,
611                                         bits_per_sample,
612                                         sample_word_size);
613         else
614                 ret = q6asm_enc_cfg_blk_pcm_format_support_v4(
615                                         prtd->audio_client,
616                                         prtd->samp_rate,
617                                         prtd->channel_mode,
618                                         bits_per_sample,
619                                         sample_word_size,
620                                         ASM_LITTLE_ENDIAN,
621                                         DEFAULT_QF);
622         if (ret < 0)
623                 pr_debug("%s: cmd cfg pcm was block failed", __func__);
624
625         prtd->enabled = RUNNING;
626
627         return ret;
628 }
629
630 static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
631 {
632         int ret = 0;
633         struct snd_pcm_runtime *runtime = substream->runtime;
634         struct msm_audio *prtd = runtime->private_data;
635
636         switch (cmd) {
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);
642                 break;
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);
649                         break;
650                 }
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);
655                 if (ret)
656                         clear_bit(CMD_EOS, &prtd->cmd_pending);
657                 break;
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);
663                 break;
664         default:
665                 ret = -EINVAL;
666                 break;
667         }
668
669         return ret;
670 }
671
672 static int msm_pcm_open(struct snd_pcm_substream *substream)
673 {
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;
678         int ret = 0;
679
680         pdata = (struct msm_plat_data *)
681                 dev_get_drvdata(soc_prtd->platform->dev);
682         if (!pdata) {
683                 pr_err("%s: platform data not populated\n", __func__);
684                 return -EINVAL;
685         }
686         prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL);
687         if (prtd == NULL) {
688                 pr_err("Failed to allocate memory for msm_audio\n");
689                 return -ENOMEM;
690         }
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__);
696                 kfree(prtd);
697                 prtd = NULL;
698                 return -ENOMEM;
699         }
700
701         prtd->audio_client->dev = soc_prtd->platform->dev;
702
703         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
704                 runtime->hw = msm_pcm_hardware_playback;
705
706         /* Capture path */
707         else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
708                 runtime->hw = msm_pcm_hardware_capture;
709         else {
710                 pr_err("Invalid Stream type %d\n", substream->stream);
711                 return -EINVAL;
712         }
713
714         ret = snd_pcm_hw_constraint_list(runtime, 0,
715                                 SNDRV_PCM_HW_PARAM_RATE,
716                                 &constraints_sample_rates);
717         if (ret < 0)
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);
722         if (ret < 0)
723                 pr_info("snd_pcm_hw_constraint_integer failed\n");
724
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);
730                 if (ret < 0) {
731                         pr_err("constraint for buffer bytes min max ret = %d\n",
732                                                                         ret);
733                 }
734         }
735
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);
741                 if (ret < 0) {
742                         pr_err("constraint for buffer bytes min max ret = %d\n",
743                                                                         ret);
744                 }
745         }
746         ret = snd_pcm_hw_constraint_step(runtime, 0,
747                 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
748         if (ret < 0) {
749                 pr_err("constraint for period bytes step ret = %d\n",
750                                                                 ret);
751         }
752         ret = snd_pcm_hw_constraint_step(runtime, 0,
753                 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
754         if (ret < 0) {
755                 pr_err("constraint for buffer bytes step ret = %d\n",
756                                                                 ret);
757         }
758
759         prtd->enabled = IDLE;
760         prtd->dsp_cnt = 0;
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);
769
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);
774
775         return 0;
776 }
777
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)
780 {
781         int ret = 0;
782         int fbytes = 0;
783         int xfer = 0;
784         char *bufptr = NULL;
785         void *data = NULL;
786         uint32_t idx = 0;
787         uint32_t size = 0;
788         uint32_t retries = 0;
789
790         struct snd_pcm_runtime *runtime = substream->runtime;
791         struct msm_audio *prtd = runtime->private_data;
792
793         fbytes = frames_to_bytes(runtime, frames);
794         pr_debug("%s: prtd->out_count = %d\n",
795                                 __func__, atomic_read(&prtd->out_count));
796
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",
800                                 __func__);
801                         return -ENETRESET;
802                 }
803
804                 ret = wait_event_timeout(the_locks.write_wait,
805                                 (atomic_read(&prtd->out_count)), 5 * HZ);
806                 if (!ret) {
807                         pr_err("%s: wait_event_timeout failed\n", __func__);
808                         ret = -ETIMEDOUT;
809                         goto fail;
810                 }
811                 ret = 0;
812
813                 if (prtd->reset_event) {
814                         pr_err("%s: In SSR return ENETRESET after wait\n",
815                                 __func__);
816                         return -ENETRESET;
817                 }
818
819                 if (!atomic_read(&prtd->out_count)) {
820                         pr_err("%s: pcm stopped out_count 0\n", __func__);
821                         return 0;
822                 }
823
824                 data = q6asm_is_cpu_buf_avail(IN, prtd->audio_client, &size,
825                         &idx);
826                 if (data == NULL) {
827                         retries++;
828                         continue;
829                 } else {
830                         retries = 0;
831                 }
832
833                 if (fbytes > size)
834                         xfer = size;
835                 else
836                         xfer = fbytes;
837
838                 bufptr = data;
839                 if (bufptr) {
840                         pr_debug("%s:fbytes =%d: xfer=%d size=%d\n",
841                                                 __func__, fbytes, xfer, size);
842                         if (copy_from_user(bufptr, buf, xfer)) {
843                                 ret = -EFAULT;
844                                 pr_err("%s: copy_from_user failed\n",
845                                         __func__);
846                                 q6asm_cpu_buf_release(IN, prtd->audio_client);
847                                 goto fail;
848                         }
849                         buf += xfer;
850                         fbytes -= xfer;
851                         pr_debug("%s:fbytes = %d: xfer=%d\n", __func__, fbytes,
852                                 xfer);
853                         if (atomic_read(&prtd->start)) {
854                                 pr_debug("%s:writing %d bytes of buffer to dsp\n",
855                                                 __func__, xfer);
856                                 ret = q6asm_write(prtd->audio_client, xfer,
857                                                         0, 0, NO_TIMESTAMP);
858                                 if (ret < 0) {
859                                         ret = -EFAULT;
860                                         q6asm_cpu_buf_release(IN,
861                                                 prtd->audio_client);
862                                         goto fail;
863                                 }
864                         } else
865                                 atomic_inc(&prtd->out_needed);
866                         atomic_dec(&prtd->out_count);
867                 }
868         }
869 fail:
870         if (retries >= MAX_PB_COPY_RETRIES)
871                 ret = -ENOMEM;
872
873         return  ret;
874 }
875
876 static int msm_pcm_playback_close(struct snd_pcm_substream *substream)
877 {
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;
882         uint32_t timeout;
883         int dir = 0;
884         int ret = 0;
885
886         pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending);
887
888         if (prtd->audio_client) {
889                 dir = IN;
890
891                 /*
892                  * Unvote to downgrade the Rx thread priority from
893                  * RT Thread for Low-Latency use case.
894                  */
895                 pdata = (struct msm_plat_data *)
896                         dev_get_drvdata(soc_prtd->platform->dev);
897                 if (pdata) {
898                         if (pdata->perf_mode == LOW_LATENCY_PCM_MODE)
899                                 apr_end_rx_rt(prtd->audio_client->apr);
900                 }
901                 /* determine timeout length */
902                 if (runtime->frame_bits == 0 || runtime->rate == 0) {
903                         timeout = CMD_EOS_MIN_TIMEOUT_LENGTH;
904                 } else {
905                         timeout = (runtime->period_size *
906                                         CMD_EOS_TIMEOUT_MULTIPLIER) /
907                                         ((runtime->frame_bits / 8) *
908                                          runtime->rate);
909                         if (timeout < CMD_EOS_MIN_TIMEOUT_LENGTH)
910                                 timeout = CMD_EOS_MIN_TIMEOUT_LENGTH;
911                 }
912                 pr_debug("%s: CMD_EOS timeout is %d\n", __func__, timeout);
913
914                 ret = wait_event_timeout(the_locks.eos_wait,
915                                          !test_bit(CMD_EOS, &prtd->cmd_pending),
916                                          timeout);
917                 if (!ret)
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,
922                                         prtd->audio_client);
923                 q6asm_audio_client_free(prtd->audio_client);
924         }
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);
928         kfree(prtd);
929         runtime->private_data = NULL;
930
931         return 0;
932 }
933
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)
937 {
938         int ret = 0;
939         int fbytes = 0;
940         int xfer;
941         char *bufptr;
942         void *data = NULL;
943         static uint32_t idx;
944         static uint32_t size;
945         uint32_t offset = 0;
946         struct snd_pcm_runtime *runtime = substream->runtime;
947         struct msm_audio *prtd = substream->runtime->private_data;
948
949
950         pr_debug("%s\n", __func__);
951         fbytes = frames_to_bytes(runtime, frames);
952
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);
956
957         if (prtd->reset_event) {
958                 pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
959                 return -ENETRESET;
960         }
961         ret = wait_event_timeout(the_locks.read_wait,
962                         (atomic_read(&prtd->in_count)), 5 * HZ);
963         if (!ret) {
964                 pr_debug("%s: wait_event_timeout failed\n", __func__);
965                 goto fail;
966         }
967         if (prtd->reset_event) {
968                 pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
969                 return -ENETRESET;
970         }
971         if (!atomic_read(&prtd->in_count)) {
972                 pr_debug("%s: pcm stopped in_count 0\n", __func__);
973                 return 0;
974         }
975         pr_debug("Checking if valid buffer is available...%pK\n",
976                                                 data);
977         data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx);
978         bufptr = data;
979         pr_debug("Size = %d\n", size);
980         pr_debug("fbytes = %d\n", fbytes);
981         pr_debug("idx = %d\n", idx);
982         if (bufptr) {
983                 xfer = fbytes;
984                 if (xfer > size)
985                         xfer = size;
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");
990                         ret = -EFAULT;
991                         q6asm_cpu_buf_release(OUT, prtd->audio_client);
992                         goto fail;
993                 }
994                 fbytes -= xfer;
995                 size -= xfer;
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);
1004                 if (ret < 0) {
1005                         pr_err("q6asm read failed\n");
1006                         ret = -EFAULT;
1007                         q6asm_cpu_buf_release(OUT, prtd->audio_client);
1008                         goto fail;
1009                 }
1010         } else
1011                 pr_err("No valid buffer\n");
1012
1013         pr_debug("Returning from capture_copy... %d\n", ret);
1014 fail:
1015         return ret;
1016 }
1017
1018 static int msm_pcm_capture_close(struct snd_pcm_substream *substream)
1019 {
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;
1023         int dir = OUT;
1024
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);
1031         }
1032
1033         msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
1034                 SNDRV_PCM_STREAM_CAPTURE);
1035         kfree(prtd);
1036         runtime->private_data = NULL;
1037
1038         return 0;
1039 }
1040
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)
1043 {
1044         int ret = 0;
1045
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);
1050         return ret;
1051 }
1052
1053 static int msm_pcm_close(struct snd_pcm_substream *substream)
1054 {
1055         int ret = 0;
1056
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);
1061         return ret;
1062 }
1063
1064 static int msm_pcm_prepare(struct snd_pcm_substream *substream)
1065 {
1066         int ret = 0;
1067
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);
1072         return ret;
1073 }
1074
1075 static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream)
1076 {
1077
1078         struct snd_pcm_runtime *runtime = substream->runtime;
1079         struct msm_audio *prtd = runtime->private_data;
1080
1081         if (prtd->pcm_irq_pos >= prtd->pcm_size)
1082                 prtd->pcm_irq_pos = 0;
1083
1084         pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
1085         return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
1086 }
1087
1088 static int msm_pcm_mmap(struct snd_pcm_substream *substream,
1089                                 struct vm_area_struct *vma)
1090 {
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;
1096         int dir = -1;
1097
1098         prtd->mmap_flag = 1;
1099
1100         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1101                 dir = IN;
1102         else
1103                 dir = OUT;
1104         ab = &(apd[dir].buf[0]);
1105
1106         return msm_audio_ion_mmap(ab, vma);
1107 }
1108
1109 static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
1110                                 struct snd_pcm_hw_params *params)
1111 {
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;
1116         int dir, ret;
1117
1118         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1119                 dir = IN;
1120         else
1121                 dir = OUT;
1122         ret = q6asm_audio_client_buf_alloc_contiguous(dir,
1123                         prtd->audio_client,
1124                         (params_buffer_bytes(params) / params_periods(params)),
1125                          params_periods(params));
1126         if (ret < 0) {
1127                 pr_err("Audio Start: Buffer Allocation failed rc = %d\n",
1128                                                         ret);
1129                 return -ENOMEM;
1130         }
1131         buf = prtd->audio_client->port[dir].buf;
1132         if (buf == NULL || buf[0].data == NULL)
1133                 return -ENOMEM;
1134
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);
1142         if (!dma_buf->area)
1143                 return -ENOMEM;
1144
1145         snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
1146         return 0;
1147 }
1148
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,
1159 };
1160
1161 static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
1162                                 struct snd_ctl_elem_value *ucontrol)
1163 {
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;
1169         int ret = 0;
1170         struct msm_adsp_event_data *event_data = NULL;
1171         uint64_t actual_payload_len = 0;
1172
1173         if (!pdata) {
1174                 pr_err("%s pdata is NULL\n", __func__);
1175                 ret = -ENODEV;
1176                 goto done;
1177         }
1178
1179         substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1180         if (!substream) {
1181                 pr_err("%s substream not found\n", __func__);
1182                 ret = -EINVAL;
1183                 goto done;
1184         }
1185
1186         if (!substream->runtime) {
1187                 pr_err("%s substream runtime not found\n", __func__);
1188                 ret = -EINVAL;
1189                 goto done;
1190         }
1191
1192         prtd = substream->runtime->private_data;
1193         if (prtd == NULL) {
1194                 pr_err("%s prtd is null.\n", __func__);
1195                 ret = -EINVAL;
1196                 goto done;
1197         }
1198
1199         if (prtd->audio_client == NULL) {
1200                 pr_err("%s prtd is null.\n", __func__);
1201                 ret = -EINVAL;
1202                 goto done;
1203         }
1204
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);
1210                 ret = -EINVAL;
1211                 goto done;
1212         }
1213
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);
1219                 ret = -EINVAL;
1220                 goto done;
1221         }
1222
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);
1227                 ret = -EINVAL;
1228                 goto done;
1229         }
1230
1231         ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
1232         if (ret < 0)
1233                 pr_err("%s: failed to send stream event cmd, err = %d\n",
1234                         __func__, ret);
1235 done:
1236         return ret;
1237 }
1238
1239 static int msm_pcm_add_audio_adsp_stream_cmd_control(
1240                         struct snd_soc_pcm_runtime *rtd)
1241 {
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] = {
1247                 {
1248                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1249                 .name = "?",
1250                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1251                 .info = msm_adsp_stream_cmd_info,
1252                 .put = msm_pcm_adsp_stream_cmd_put,
1253                 .private_value = 0,
1254                 }
1255         };
1256
1257         if (!rtd) {
1258                 pr_err("%s rtd is NULL\n", __func__);
1259                 ret = -EINVAL;
1260                 goto done;
1261         }
1262
1263         ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
1264         mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1265         if (!mixer_str) {
1266                 ret = -ENOMEM;
1267                 goto done;
1268         }
1269
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));
1278         if (ret < 0)
1279                 pr_err("%s: failed add ctl %s. err = %d\n",
1280                         __func__, mixer_str, ret);
1281
1282         kfree(mixer_str);
1283 done:
1284         return ret;
1285 }
1286
1287 static int msm_pcm_add_audio_adsp_stream_callback_control(
1288                         struct snd_soc_pcm_runtime *rtd)
1289 {
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;
1295
1296         struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = {
1297                 {
1298                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1299                 .name = "?",
1300                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1301                 .info = msm_adsp_stream_callback_info,
1302                 .get = msm_adsp_stream_callback_get,
1303                 .private_value = 0,
1304                 }
1305         };
1306
1307         if (!rtd) {
1308                 pr_err("%s NULL rtd\n", __func__);
1309                 ret = -EINVAL;
1310                 goto done;
1311         }
1312
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);
1318         if (!mixer_str) {
1319                 ret = -ENOMEM;
1320                 goto done;
1321         }
1322
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));
1331         if (ret < 0) {
1332                 pr_err("%s: failed to add ctl %s. err = %d\n",
1333                         __func__, mixer_str, ret);
1334                 ret = -EINVAL;
1335                 goto free_mixer_str;
1336         }
1337
1338         kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
1339         if (!kctl) {
1340                 pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
1341                 ret = -EINVAL;
1342                 goto free_mixer_str;
1343         }
1344
1345         kctl->private_data = NULL;
1346
1347 free_mixer_str:
1348         kfree(mixer_str);
1349 done:
1350         return ret;
1351 }
1352
1353 static int msm_pcm_set_volume(struct msm_audio *prtd, uint32_t volume)
1354 {
1355         int rc = 0;
1356
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);
1361                 if (rc < 0) {
1362                         pr_err("%s: Send Volume command failed rc=%d\n",
1363                                         __func__, rc);
1364                 }
1365         }
1366         return rc;
1367 }
1368
1369 static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol,
1370                       struct snd_ctl_elem_value *ucontrol)
1371 {
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;
1376
1377         pr_debug("%s\n", __func__);
1378         if (!substream) {
1379                 pr_err("%s substream not found\n", __func__);
1380                 return -ENODEV;
1381         }
1382         if (!substream->runtime) {
1383                 pr_err("%s substream runtime not found\n", __func__);
1384                 return 0;
1385         }
1386         prtd = substream->runtime->private_data;
1387         if (prtd)
1388                 ucontrol->value.integer.value[0] = prtd->volume;
1389         return 0;
1390 }
1391
1392 static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
1393                                 struct snd_ctl_elem_value *ucontrol)
1394 {
1395         int rc = 0;
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];
1401
1402         pr_debug("%s: volume : 0x%x\n", __func__, volume);
1403         if (!substream) {
1404                 pr_err("%s substream not found\n", __func__);
1405                 return -ENODEV;
1406         }
1407         if (!substream->runtime) {
1408                 pr_err("%s substream runtime not found\n", __func__);
1409                 return 0;
1410         }
1411         prtd = substream->runtime->private_data;
1412         if (prtd) {
1413                 rc = msm_pcm_set_volume(prtd, volume);
1414                 prtd->volume = volume;
1415         }
1416         return rc;
1417 }
1418
1419 static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd)
1420 {
1421         int ret = 0;
1422         struct snd_pcm *pcm = rtd->pcm;
1423         struct snd_pcm_volume *volume_info;
1424         struct snd_kcontrol *kctl;
1425
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,
1429                         &volume_info);
1430         if (ret < 0) {
1431                 pr_err("%s volume control failed ret %d\n", __func__, ret);
1432                 return ret;
1433         }
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;
1438         return 0;
1439 }
1440
1441 static int msm_pcm_compress_ctl_info(struct snd_kcontrol *kcontrol,
1442                                 struct snd_ctl_elem_info *uinfo)
1443 {
1444         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1445         uinfo->count = 1;
1446         uinfo->value.integer.min = 0;
1447         uinfo->value.integer.max = 0x2000;
1448         return 0;
1449 }
1450
1451 static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
1452                       struct snd_ctl_elem_value *ucontrol)
1453 {
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;
1459
1460         if (!pdata) {
1461                 pr_err("%s pdata is NULL\n", __func__);
1462                 return -ENODEV;
1463         }
1464         substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1465         if (!substream) {
1466                 pr_err("%s substream not found\n", __func__);
1467                 return -EINVAL;
1468         }
1469         if (!substream->runtime) {
1470                 pr_err("%s substream runtime not found\n", __func__);
1471                 return 0;
1472         }
1473         prtd = substream->runtime->private_data;
1474         if (prtd)
1475                 ucontrol->value.integer.value[0] = prtd->compress_enable;
1476         return 0;
1477 }
1478
1479 static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
1480                                 struct snd_ctl_elem_value *ucontrol)
1481 {
1482         int rc = 0;
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];
1489
1490         if (!pdata) {
1491                 pr_err("%s pdata is NULL\n", __func__);
1492                 return -ENODEV;
1493         }
1494         substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1495         pr_debug("%s: compress : 0x%x\n", __func__, compress);
1496         if (!substream) {
1497                 pr_err("%s substream not found\n", __func__);
1498                 return -EINVAL;
1499         }
1500         if (!substream->runtime) {
1501                 pr_err("%s substream runtime not found\n", __func__);
1502                 return 0;
1503         }
1504         prtd = substream->runtime->private_data;
1505         if (prtd) {
1506                 pr_debug("%s: setting compress flag to 0x%x\n",
1507                 __func__, compress);
1508                 prtd->compress_enable = compress;
1509         }
1510         return rc;
1511 }
1512
1513 static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
1514 {
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;
1519         int ctl_len;
1520         int ret = 0;
1521         struct msm_plat_data *pdata;
1522         struct snd_kcontrol_new pcm_compress_control[1] = {
1523                 {
1524                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525                 .name = "?",
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,
1530                 .private_value = 0,
1531                 }
1532         };
1533
1534         if (!rtd) {
1535                 pr_err("%s: NULL rtd\n", __func__);
1536                 return -EINVAL;
1537         }
1538
1539         ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) +
1540                   strlen(mixer_ctl_end_name) + 1;
1541         mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1542
1543         if (!mixer_str)
1544                 return -ENOMEM;
1545
1546         snprintf(mixer_str, ctl_len, "%s%d%s", mixer_ctl_name,
1547                         rtd->pcm->device, mixer_ctl_end_name);
1548
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);
1553         if (pdata) {
1554                 if (!pdata->pcm) {
1555                         pdata->pcm = rtd->pcm;
1556                         ret = snd_soc_add_platform_controls(rtd->platform,
1557                                                         pcm_compress_control,
1558                                                         ARRAY_SIZE
1559                                                         (pcm_compress_control));
1560                         if (ret < 0)
1561                                 pr_err("%s: failed add ctl %s. err = %d\n",
1562                                         __func__, mixer_str, ret);
1563                 }
1564         } else {
1565                 pr_err("%s: NULL pdata\n", __func__);
1566                 ret = -EINVAL;
1567         }
1568         kfree(mixer_str);
1569         return ret;
1570 }
1571
1572 static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1573                                 struct snd_ctl_elem_value *ucontrol)
1574 {
1575         int i;
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;
1580
1581         pr_debug("%s", __func__);
1582         substream = snd_pcm_chmap_substream(info, idx);
1583         if (!substream)
1584                 return -ENODEV;
1585         if (!substream->runtime)
1586                 return 0;
1587
1588         prtd = substream->runtime->private_data;
1589         if (prtd) {
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]);
1594         }
1595         return 0;
1596 }
1597
1598 static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
1599                                 struct snd_ctl_elem_value *ucontrol)
1600 {
1601         int i;
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;
1606
1607         pr_debug("%s", __func__);
1608         substream = snd_pcm_chmap_substream(info, idx);
1609         if (!substream)
1610                 return -ENODEV;
1611         memset(ucontrol->value.integer.value, 0,
1612                 sizeof(ucontrol->value.integer.value));
1613         if (!substream->runtime)
1614                 return 0; /* no channels set */
1615
1616         prtd = substream->runtime->private_data;
1617
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];
1622         } else {
1623                 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
1624                         ucontrol->value.integer.value[i] = 0;
1625         }
1626
1627         return 0;
1628 }
1629
1630 static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
1631 {
1632         struct snd_pcm *pcm = rtd->pcm;
1633         struct snd_pcm_chmap *chmap_info;
1634         struct snd_kcontrol *kctl;
1635         char device_num[12];
1636         int i, ret = 0;
1637
1638         pr_debug("%s, Channel map cntrl add\n", __func__);
1639         ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1640                                      snd_pcm_std_chmaps,
1641                                      PCM_FORMAT_MAX_NUM_CHANNEL_V2, 0,
1642                                      &chmap_info);
1643         if (ret < 0) {
1644                 pr_err("%s, channel map cntrl add failed\n", __func__);
1645                 return ret;
1646         }
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;
1656         return 0;
1657 }
1658
1659 static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
1660                                         struct snd_ctl_elem_value *ucontrol)
1661 {
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};
1666         int ret = 0;
1667
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,
1679                                                       be_id, &cfg_data);
1680         if (ret < 0)
1681                 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
1682                         __func__, ret);
1683
1684         return ret;
1685 }
1686
1687 static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
1688                                         struct snd_ctl_elem_value *ucontrol)
1689 {
1690         u64 fe_id = kcontrol->private_value;
1691         int session_type = SESSION_TYPE_RX;
1692         int be_id = 0;
1693         struct msm_pcm_stream_app_type_cfg cfg_data = {0};
1694         int ret = 0;
1695
1696         ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
1697                                                       &be_id, &cfg_data);
1698         if (ret < 0) {
1699                 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
1700                         __func__, ret);
1701                 goto done;
1702         }
1703
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);
1713 done:
1714         return ret;
1715 }
1716
1717 static int msm_pcm_playback_pan_scale_ctl_info(struct snd_kcontrol *kcontrol,
1718                                         struct snd_ctl_elem_info *uinfo)
1719 {
1720         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1721         uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
1722         return 0;
1723 }
1724
1725 static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
1726                                         struct snd_ctl_elem_value *ucontrol)
1727 {
1728         int ret = 0;
1729         int len = 0;
1730         int i = 0;
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;
1739
1740         if (!usr_info) {
1741                 pr_err("%s: usr_info is null\n", __func__);
1742                 ret = -EINVAL;
1743                 goto done;
1744         }
1745
1746         platform = snd_soc_component_to_platform(usr_info);
1747         if (!platform) {
1748                 pr_err("%s: platform is null\n", __func__);
1749                 ret = -EINVAL;
1750                 goto done;
1751         }
1752         pdata = dev_get_drvdata(platform->dev);
1753         if (!pdata) {
1754                 pr_err("%s: pdata is null\n", __func__);
1755                 ret = -EINVAL;
1756                 goto done;
1757         }
1758         substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1759         if (!substream) {
1760                 pr_err("%s substream not found\n", __func__);
1761                 ret = -EINVAL;
1762                 goto done;
1763         }
1764
1765         if (!substream->runtime) {
1766                 pr_err("%s substream runtime not found\n", __func__);
1767                 ret = -EINVAL;
1768                 goto done;
1769         }
1770         prtd = substream->runtime->private_data;
1771         if (!prtd) {
1772                 ret = -EINVAL;
1773                 goto done;
1774         }
1775         usr_value = (char *) ucontrol->value.bytes.data;
1776         if (!usr_value) {
1777                 pr_err("%s ucontrol data is null\n", __func__);
1778                 ret = -EINVAL;
1779                 goto done;
1780         }
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) {
1786                 ret = -EINVAL;
1787                 goto done;
1788         }
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) {
1794                 ret = -EINVAL;
1795                 goto done;
1796         }
1797
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]));
1804         }
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]));
1811         }
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++) {
1816                         pan_param.gain[i] =
1817                                 !(gain_ptr[i] > 0) ?
1818                                 0 : 2 << 13;
1819                         len += sizeof(pan_param.gain[i]);
1820                 }
1821                 len += (pan_param.num_input_channels *
1822                 pan_param.num_output_channels * sizeof(pan_param.gain[0]));
1823         }
1824
1825         ret = q6asm_set_mfc_panning_params(prtd->audio_client,
1826                                            &pan_param);
1827         len -= pan_param.num_output_channels *
1828                 pan_param.num_input_channels * sizeof(pan_param.gain[0]);
1829         if (gain_ptr) {
1830                 for (i = 0; i < pan_param.num_output_channels *
1831                         pan_param.num_input_channels; i++) {
1832                         /*
1833                          * The data userspace passes is already in Q14 format.
1834                          * For volume gain is in Q28.
1835                          */
1836                         pan_param.gain[i] =
1837                                 (gain_ptr[i]) << 14;
1838                         len += sizeof(pan_param.gain[i]);
1839                 }
1840         }
1841         ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
1842                                            &pan_param);
1843
1844 done:
1845         return ret;
1846 }
1847
1848 static int msm_pcm_playback_pan_scale_ctl_get(struct snd_kcontrol *kcontrol,
1849                                         struct snd_ctl_elem_value *ucontrol)
1850 {
1851         return 0;
1852 }
1853
1854 static int msm_add_stream_pan_scale_controls(struct snd_soc_pcm_runtime *rtd)
1855 {
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;
1860         int ctl_len;
1861         int ret = 0;
1862         struct msm_plat_data *pdata;
1863         struct snd_kcontrol_new pan_scale_control[1] = {
1864                 {
1865                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1866                 .name = "?",
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,
1871                 .private_value = 0,
1872                 }
1873         };
1874
1875         if (!rtd) {
1876                 pr_err("%s: NULL rtd\n", __func__);
1877                 return -EINVAL;
1878         }
1879
1880         ctl_len = strlen(playback_mixer_ctl_name) + 1 +
1881         strlen(deviceNo) + 1 + strlen(suffix) + 1;
1882         mixer_str = kzalloc(ctl_len, GFP_KERNEL);
1883         if (!mixer_str) {
1884                 ret = -ENOMEM;
1885                 goto done;
1886         }
1887
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);
1894         if (pdata) {
1895                 if (!pdata->pcm)
1896                         pdata->pcm = rtd->pcm;
1897                 ret = snd_soc_add_platform_controls(rtd->platform,
1898                                                         pan_scale_control,
1899                                                         ARRAY_SIZE
1900                                                         (pan_scale_control));
1901                 if (ret < 0)
1902                         pr_err("%s: failed add ctl %s. err = %d\n",
1903                                         __func__, mixer_str, ret);
1904         } else {
1905                 pr_err("%s: NULL pdata\n", __func__);
1906                 ret = -EINVAL;
1907         }
1908
1909         kfree(mixer_str);
1910 done:
1911         return ret;
1912
1913 }
1914
1915 static int msm_pcm_playback_dnmix_ctl_get(struct snd_kcontrol *kcontrol,
1916                                         struct snd_ctl_elem_value *ucontrol)
1917 {
1918         return 0;
1919 }
1920
1921 static int msm_pcm_playback_dnmix_ctl_info(struct snd_kcontrol *kcontrol,
1922                                         struct snd_ctl_elem_info *uinfo)
1923 {
1924         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1925         uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
1926         return 0;
1927 }
1928
1929 static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
1930                                         struct snd_ctl_elem_value *ucontrol)
1931 {
1932         int ret = 0;
1933         int len = 0;
1934
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;
1941         char *usr_value;
1942         int be_id = 0;
1943         int stream_id = 0;
1944
1945         if (!usr_info) {
1946                 pr_err("%s usr_info is null\n", __func__);
1947                 ret = -EINVAL;
1948                 goto done;
1949         }
1950         platform = snd_soc_component_to_platform(usr_info);
1951         if (!platform) {
1952                 pr_err("%s platform is null\n", __func__);
1953                 ret = -EINVAL;
1954                 goto done;
1955         }
1956         pdata = dev_get_drvdata(platform->dev);
1957         if (!pdata) {
1958                 pr_err("%s pdata is null\n", __func__);
1959                 ret = -EINVAL;
1960                 goto done;
1961         }
1962         substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1963         if (!substream) {
1964                 pr_err("%s substream not found\n", __func__);
1965                 ret = -EINVAL;
1966                 goto done;
1967         }
1968         if (!substream->runtime) {
1969                 pr_err("%s substream runtime not found\n", __func__);
1970                 ret = -EINVAL;
1971                 goto done;
1972         }
1973         prtd = substream->runtime->private_data;
1974         if (!prtd) {
1975                 ret = -EINVAL;
1976                 goto done;
1977         }
1978         usr_value = (char *) ucontrol->value.bytes.data;
1979         if (!usr_value) {
1980                 pr_err("%s usrvalue is null\n", __func__);
1981                 goto done;
1982         }
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) {
1991                 ret = -EINVAL;
1992                 goto done;
1993         }
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) {
1999                 ret = -EINVAL;
2000                 goto done;
2001         }
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]));
2008         }
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]));
2015         }
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]));
2023         }
2024         msm_routing_set_downmix_control_data(be_id,
2025                                              stream_id,
2026                                              &dnmix_param);
2027
2028 done:
2029         return ret;
2030 }
2031
2032 static int msm_add_device_down_mix_controls(struct snd_soc_pcm_runtime *rtd)
2033 {
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] = {
2041                 {
2042                         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2043                         .name = "?",
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,
2048                         .private_value = 0,
2049                 }
2050         };
2051
2052         if (!rtd) {
2053                 pr_err("%s NULL rtd\n", __func__);
2054                 ret = -EINVAL;
2055                 goto done;
2056         }
2057         ctl_len = strlen(playback_mixer_ctl_name) + 1 +
2058         strlen(deviceNo) + 1 + strlen(suffix) + 1;
2059         mixer_str = kzalloc(ctl_len, GFP_KERNEL);
2060         if (!mixer_str) {
2061                 ret = -ENOMEM;
2062                 goto done;
2063         }
2064
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);
2071         if (pdata) {
2072                 if (!pdata->pcm)
2073                         pdata->pcm = rtd->pcm;
2074                 ret = snd_soc_add_platform_controls(rtd->platform,
2075                                                       device_downmix_control,
2076                                                       ARRAY_SIZE
2077                                                       (device_downmix_control));
2078                 if (ret < 0)
2079                         pr_err("%s: failed add ctl %s. err = %d\n",
2080                                  __func__, mixer_str, ret);
2081         } else {
2082                 pr_err("%s: NULL pdata\n", __func__);
2083                 ret = -EINVAL;
2084         }
2085         kfree(mixer_str);
2086 done:
2087         return ret;
2088 }
2089
2090 static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
2091                                         struct snd_ctl_elem_value *ucontrol)
2092 {
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};
2097         int ret = 0;
2098
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,
2110                                                       be_id, &cfg_data);
2111         if (ret < 0)
2112                 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
2113                         __func__, ret);
2114
2115         return ret;
2116 }
2117
2118 static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
2119                                         struct snd_ctl_elem_value *ucontrol)
2120 {
2121         u64 fe_id = kcontrol->private_value;
2122         int session_type = SESSION_TYPE_TX;
2123         int be_id = 0;
2124         struct msm_pcm_stream_app_type_cfg cfg_data = {0};
2125         int ret = 0;
2126
2127         ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
2128                                                       &be_id, &cfg_data);
2129         if (ret < 0) {
2130                 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
2131                         __func__, ret);
2132                 goto done;
2133         }
2134
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);
2144 done:
2145         return ret;
2146 }
2147
2148 static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
2149 {
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;
2158
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,
2165                                         &app_type_info);
2166                 if (ret < 0) {
2167                         pr_err("%s: playback app type cntrl add failed: %d\n",
2168                                 __func__, ret);
2169                         return ret;
2170                 }
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;
2176         }
2177
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,
2184                                         &app_type_info);
2185                 if (ret < 0) {
2186                         pr_err("%s: capture app type cntrl add failed: %d\n",
2187                                 __func__, ret);
2188                         return ret;
2189                 }
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;
2195         }
2196
2197         return 0;
2198 }
2199
2200 static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
2201                         struct snd_ctl_elem_value *ucontrol)
2202 {
2203         u64 fe_id = kcontrol->private_value & 0xFF;
2204         int session_type = (kcontrol->private_value >> 8) & 0xFF;
2205         int ret = 0;
2206         int stream_id = 0;
2207         int be_id = 0;
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;
2215
2216         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2217                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2218                 return -EINVAL;
2219         }
2220
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);
2224                 return -EINVAL;
2225         }
2226
2227         pcm = pdata->pcm_device[fe_id];
2228         if (!pcm) {
2229                 pr_err("%s invalid pcm handle for fe_id %llu\n",
2230                                 __func__, fe_id);
2231                 ret = -EINVAL;
2232                 goto done;
2233         }
2234
2235         if (session_type == SESSION_TYPE_RX)
2236                 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
2237         else
2238                 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
2239         if (!substream) {
2240                 pr_err("%s substream not found\n", __func__);
2241                 ret = -EINVAL;
2242                 goto done;
2243         }
2244
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];
2251
2252         /* cache value and take effect during adm_open stage */
2253         msm_pcm_routing_set_channel_mixer_cfg(fe_id,
2254                         session_type,
2255                         chmixer_pspd);
2256
2257         if (substream->runtime) {
2258                 prtd = substream->runtime->private_data;
2259                 if (!prtd) {
2260                         pr_err("%s find invalid prtd fail\n", __func__);
2261                         return -EINVAL;
2262                 }
2263
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,
2268                                         stream_id,
2269                                         session_type,
2270                                         chmixer_pspd);
2271                 }
2272         }
2273 done:
2274         return ret;
2275 }
2276
2277 static int msm_pcm_channel_mixer_cfg_ctl_get(struct snd_kcontrol *kcontrol,
2278                                         struct snd_ctl_elem_value *ucontrol)
2279 {
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;
2286
2287         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2288                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2289                 return -EINVAL;
2290         }
2291
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);
2295                 return -EINVAL;
2296         }
2297
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;
2304         return 0;
2305 }
2306
2307 static int msm_pcm_channel_mixer_output_map_ctl_put(
2308                 struct snd_kcontrol *kcontrol,
2309                 struct snd_ctl_elem_value *ucontrol)
2310 {
2311         u64 fe_id = kcontrol->private_value & 0xFF;
2312         int session_type = (kcontrol->private_value >> 8) & 0xFF;
2313         int i = 0;
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;
2318
2319         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2320                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2321                 return -EINVAL;
2322         }
2323
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);
2327                 return -EINVAL;
2328         }
2329
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];
2334
2335         return 0;
2336 }
2337
2338 static int msm_pcm_channel_mixer_output_map_ctl_get(
2339                 struct snd_kcontrol *kcontrol,
2340                 struct snd_ctl_elem_value *ucontrol)
2341 {
2342         u64 fe_id = kcontrol->private_value & 0xFF;
2343         int session_type = (kcontrol->private_value >> 8) & 0xFF;
2344         int i = 0;
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;
2349
2350         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2351                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2352                 return -EINVAL;
2353         }
2354
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);
2358                 return -EINVAL;
2359         }
2360
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];
2365         return 0;
2366 }
2367
2368 static int msm_pcm_channel_mixer_input_map_ctl_put(
2369                 struct snd_kcontrol *kcontrol,
2370                 struct snd_ctl_elem_value *ucontrol)
2371 {
2372         u64 fe_id = kcontrol->private_value & 0xFF;
2373         int session_type = (kcontrol->private_value >> 8) & 0xFF;
2374         int i = 0;
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;
2379
2380         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2381                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2382                 return -EINVAL;
2383         }
2384
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);
2388                 return -EINVAL;
2389         }
2390
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];
2394
2395         return 0;
2396 }
2397
2398 static int msm_pcm_channel_mixer_input_map_ctl_get(
2399                 struct snd_kcontrol *kcontrol,
2400                 struct snd_ctl_elem_value *ucontrol)
2401 {
2402         u64 fe_id = kcontrol->private_value & 0xFF;
2403         int session_type = (kcontrol->private_value >> 8) & 0xFF;
2404         int i = 0;
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;
2409
2410         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2411                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2412                 return -EINVAL;
2413         }
2414
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);
2418                 return -EINVAL;
2419         }
2420
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];
2425         return 0;
2426 }
2427
2428 static int msm_pcm_channel_mixer_weight_ctl_put(
2429                 struct snd_kcontrol *kcontrol,
2430                 struct snd_ctl_elem_value *ucontrol)
2431 {
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;
2435         int i = 0;
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;
2440
2441         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2442                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2443                 return -EINVAL;
2444         }
2445
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);
2449                 return -EINVAL;
2450         }
2451
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);
2455                 return -EINVAL;
2456         }
2457
2458         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];
2462         return 0;
2463 }
2464
2465 static int msm_pcm_channel_mixer_weight_ctl_get(
2466                 struct snd_kcontrol *kcontrol,
2467                 struct snd_ctl_elem_value *ucontrol)
2468 {
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);
2475         int i = 0;
2476         struct msm_pcm_channel_mixer *chmixer_pspd;
2477
2478         if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
2479                 pr_err("%s: invalid FE %llu\n", __func__, fe_id);
2480                 return -EINVAL;
2481         }
2482
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);
2486                 return -EINVAL;
2487         }
2488
2489         if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V2) {
2490                 pr_err("%s: invalid channel number %d\n", __func__, channel);
2491                 return -EINVAL;
2492         }
2493
2494         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];
2499         return 0;
2500 }
2501
2502 static int msm_pcm_channel_mixer_output_map_info(struct snd_kcontrol *kcontrol,
2503                                        struct snd_ctl_elem_info *uinfo)
2504 {
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;
2509         return 0;
2510 }
2511
2512 static int msm_pcm_add_channel_mixer_output_map_controls(
2513                 struct snd_soc_pcm_runtime *rtd)
2514 {
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";
2520         int ctl_len = 0;
2521         int session_type = 0;
2522         char *playback_mixer_str = NULL;
2523         char *capture_mixer_str = NULL;
2524         int ret = 0;
2525         struct snd_kcontrol_new channel_mixer_output_map_control[2] = {
2526                 {
2527                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2528                 .name = "?",
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,
2533                 .private_value = 0,
2534                 },
2535                 {
2536                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2537                 .name = "?",
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,
2542                 .private_value = 0,
2543                 }
2544         };
2545
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",
2552                                         ctl_len);
2553                         goto done;
2554                 }
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],
2563                                 1);
2564                 if (ret < 0) {
2565                         pr_err("%s: failed add platform ctl, err = %d\n",
2566                                  __func__, ret);
2567                         ret = -EINVAL;
2568                         goto done;
2569                 }
2570         }
2571
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",
2578                                         ctl_len);
2579                         goto done;
2580                 }
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],
2589                                 1);
2590                 if (ret < 0) {
2591                         pr_err("%s: failed add platform ctl, err = %d\n",
2592                                  __func__, ret);
2593                         ret = -EINVAL;
2594                         goto done;
2595                 }
2596         }
2597
2598 done:
2599         kfree(playback_mixer_str);
2600         kfree(capture_mixer_str);
2601         return ret;
2602 }
2603
2604 static int msm_pcm_channel_mixer_input_map_info(struct snd_kcontrol *kcontrol,
2605                                        struct snd_ctl_elem_info *uinfo)
2606 {
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;
2611         return 0;
2612 }
2613
2614 static int msm_pcm_add_channel_mixer_input_map_controls(
2615                 struct snd_soc_pcm_runtime *rtd)
2616 {
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";
2622         int ctl_len = 0;
2623         int session_type = 0;
2624         char *playback_mixer_str = NULL;
2625         char *capture_mixer_str = NULL;
2626         int ret = 0;
2627         struct snd_kcontrol_new channel_mixer_input_map_control[2] = {
2628                 {
2629                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2630                 .name = "?",
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,
2635                 .private_value = 0,
2636                 },
2637                 {
2638                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2639                 .name = "?",
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,
2644                 .private_value = 0,
2645                 }
2646         };
2647
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",
2654                                         ctl_len);
2655                         goto done;
2656                 }
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],
2665                                         1);
2666                 if (ret < 0) {
2667                         pr_err("%s: failed add platform ctl, err = %d\n",
2668                                  __func__, ret);
2669                         ret = -EINVAL;
2670                         goto done;
2671                 }
2672         }
2673
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",
2680                                         ctl_len);
2681                         goto done;
2682                 }
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],
2691                                         1);
2692                 if (ret < 0) {
2693                         pr_err("%s: failed add platform ctl, err = %d\n",
2694                                  __func__, ret);
2695                         ret = -EINVAL;
2696                         goto done;
2697                 }
2698         }
2699
2700 done:
2701         kfree(playback_mixer_str);
2702         kfree(capture_mixer_str);
2703         return ret;
2704 }
2705
2706 static int msm_pcm_channel_mixer_cfg_info(struct snd_kcontrol *kcontrol,
2707                                        struct snd_ctl_elem_info *uinfo)
2708 {
2709         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2710         uinfo->count = 5;
2711         uinfo->value.integer.min = 0;
2712         uinfo->value.integer.max = 0xFFFFFFFF;
2713         return 0;
2714 }
2715
2716 static int msm_pcm_add_channel_mixer_cfg_controls(
2717                 struct snd_soc_pcm_runtime *rtd)
2718 {
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";
2724         int ctl_len = 0;
2725         char *playback_mixer_str = NULL;
2726         char *capture_mixer_str = NULL;
2727         int session_type = 0;
2728         int ret = 0;
2729         struct msm_plat_data *pdata = NULL;
2730         struct snd_kcontrol_new channel_mixer_cfg_control[2] = {
2731                 {
2732                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2733                 .name = "?",
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,
2738                 .private_value = 0,
2739                 },
2740                 {
2741                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2742                 .name = "?",
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,
2747                 .private_value = 0,
2748                 }
2749         };
2750
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__);
2755                 ret = -EINVAL;
2756                 goto done;
2757         }
2758
2759         pdata->pcm_device[rtd->dai_link->be_id] = rtd->pcm;
2760
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",
2767                                         ctl_len);
2768                         goto done;
2769                 }
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],
2778                                                 1);
2779                 if (ret < 0) {
2780                         pr_err("%s: failed add platform ctl, err = %d\n",
2781                                  __func__, ret);
2782                         ret = -EINVAL;
2783                         goto done;
2784                 }
2785         }
2786
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",
2793                                         ctl_len);
2794                         goto done;
2795                 }
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],
2804                                                 1);
2805                 if (ret < 0) {
2806                         pr_err("%s: failed add platform ctl, err = %d\n",
2807                                  __func__, ret);
2808                         ret = -EINVAL;
2809                         goto done;
2810                 }
2811         }
2812
2813 done:
2814         kfree(playback_mixer_str);
2815         kfree(capture_mixer_str);
2816         return ret;
2817 }
2818
2819 static int msm_pcm_channel_mixer_weight_info(struct snd_kcontrol *kcontrol,
2820                                        struct snd_ctl_elem_info *uinfo)
2821 {
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;
2826         return 0;
2827 }
2828
2829 static int msm_pcm_add_channel_mixer_weight_controls(
2830                 struct snd_soc_pcm_runtime *rtd,
2831                 int channel)
2832 {
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";
2839         int ctl_len = 0;
2840         int session_type = 0;
2841         char *playback_mixer_str = NULL;
2842         char *capture_mixer_str = NULL;
2843         int ret = 0;
2844         struct snd_kcontrol_new channel_mixer_weight_control[2] = {
2845                 {
2846                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2847                 .name = "?",
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,
2852                 .private_value = 0,
2853                 },
2854                 {
2855                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2856                 .name = "?",
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,
2861                 .private_value = 0,
2862                 }
2863         };
2864
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",
2872                                         ctl_len);
2873                         goto done;
2874                 }
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,
2878                         channel);
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)
2882                                 | (channel << 16);
2883                 ret = snd_soc_add_platform_controls(rtd->platform,
2884                                         &channel_mixer_weight_control[0],
2885                                         1);
2886                 if (ret < 0) {
2887                         pr_err("%s: failed add platform ctl, err = %d\n",
2888                                  __func__, ret);
2889                         ret = -EINVAL;
2890                         goto done;
2891                 }
2892         }
2893
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",
2901                                         ctl_len);
2902                         goto done;
2903                 }
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,
2907                         channel);
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)
2911                                 | (channel << 16);
2912                 ret = snd_soc_add_platform_controls(rtd->platform,
2913                                         &channel_mixer_weight_control[1],
2914                                         1);
2915                 if (ret < 0) {
2916                         pr_err("%s: failed add platform ctl, err = %d\n",
2917                                  __func__, ret);
2918                         ret = -EINVAL;
2919                         goto done;
2920                 }
2921         }
2922
2923 done:
2924         kfree(playback_mixer_str);
2925         kfree(capture_mixer_str);
2926         return ret;
2927 }
2928
2929 static int msm_pcm_add_channel_mixer_controls(struct snd_soc_pcm_runtime *rtd)
2930 {
2931         int i, ret = 0;
2932
2933         ret = msm_pcm_add_channel_mixer_cfg_controls(rtd);
2934         if (ret)
2935                 pr_err("%s: pcm add channel mixer cfg controls failed:%d\n",
2936                                 __func__, ret);
2937         ret = msm_pcm_add_channel_mixer_input_map_controls(rtd);
2938         if (ret)
2939                 pr_err("%s: pcm add channel mixer input map controls failed:%d\n",
2940                                 __func__, ret);
2941         ret = msm_pcm_add_channel_mixer_output_map_controls(rtd);
2942         if (ret)
2943                 pr_err("%s: pcm add channel mixer output map controls failed:%d\n",
2944                                 __func__, ret);
2945
2946         for (i = 1; i <= PCM_FORMAT_MAX_NUM_CHANNEL_V2; i++)
2947                 ret |=  msm_pcm_add_channel_mixer_weight_controls(rtd, i);
2948         if (ret)
2949                 pr_err("%s: pcm add channel mixer weight controls failed:%d\n",
2950                                 __func__, ret);
2951         return ret;
2952 }
2953
2954 static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
2955 {
2956         int ret = 0;
2957
2958         pr_debug("%s\n", __func__);
2959         ret = msm_pcm_add_chmap_controls(rtd);
2960         if (ret)
2961                 pr_err("%s: pcm add controls failed:%d\n", __func__, ret);
2962         ret = msm_pcm_add_app_type_controls(rtd);
2963         if (ret)
2964                 pr_err("%s: pcm add app type controls failed:%d\n",
2965                         __func__, ret);
2966         ret = msm_add_stream_pan_scale_controls(rtd);
2967         if (ret)
2968                 pr_err("%s: pcm add pan scale controls failed:%d\n",
2969                         __func__, ret);
2970         ret = msm_add_device_down_mix_controls(rtd);
2971         if (ret)
2972                 pr_err("%s: pcm add dnmix controls failed:%d\n",
2973                         __func__, ret);
2974         ret = msm_pcm_add_channel_mixer_controls(rtd);
2975         if (ret)
2976                 pr_err("%s: pcm add channel mixer controls failed:%d\n",
2977                         __func__, ret);
2978         return ret;
2979 }
2980
2981 static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
2982 {
2983         struct snd_card *card = rtd->card->snd_card;
2984         int ret = 0;
2985
2986         if (!card->dev->coherent_dma_mask)
2987                 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
2988
2989         ret = msm_pcm_add_controls(rtd);
2990         if (ret) {
2991                 pr_err("%s, kctl add failed:%d\n", __func__, ret);
2992                 return ret;
2993         }
2994
2995         ret = msm_pcm_add_volume_control(rtd);
2996         if (ret)
2997                 pr_err("%s: Could not add pcm Volume Control %d\n",
2998                         __func__, ret);
2999
3000         ret = msm_pcm_add_compress_control(rtd);
3001         if (ret)
3002                 pr_err("%s: Could not add pcm Compress Control %d\n",
3003                         __func__, ret);
3004
3005         ret = msm_pcm_add_audio_adsp_stream_cmd_control(rtd);
3006         if (ret)
3007                 pr_err("%s: Could not add pcm ADSP Stream Cmd Control\n",
3008                         __func__);
3009
3010         ret = msm_pcm_add_audio_adsp_stream_callback_control(rtd);
3011         if (ret)
3012                 pr_err("%s: Could not add pcm ADSP Stream Callback Control\n",
3013                         __func__);
3014
3015         return ret;
3016 }
3017
3018 static snd_pcm_sframes_t msm_pcm_delay_blk(struct snd_pcm_substream *substream,
3019                 struct snd_soc_dai *dai)
3020 {
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;
3025         int ret;
3026
3027         ret = q6asm_get_path_delay(prtd->audio_client);
3028         if (ret) {
3029                 pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret);
3030                 return 0;
3031         }
3032
3033         /* convert microseconds to frames */
3034         frames = ac->path_delay / 1000 * runtime->rate / 1000;
3035
3036         /* also convert the remainder from the initial division */
3037         frames += ac->path_delay % 1000 * runtime->rate / 1000000;
3038
3039         /* overcompensate for the loss of precision (empirical) */
3040         frames += 2;
3041
3042         return frames;
3043 }
3044
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,
3049 };
3050
3051 static int msm_pcm_probe(struct platform_device *pdev)
3052 {
3053         int rc;
3054         int id;
3055         struct msm_plat_data *pdata;
3056         const char *latency_level;
3057
3058         rc = of_property_read_u32(pdev->dev.of_node,
3059                                 "qcom,msm-pcm-dsp-id", &id);
3060         if (rc) {
3061                 dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n",
3062                                         __func__);
3063                 return rc;
3064         }
3065
3066         pdata = kzalloc(sizeof(struct msm_plat_data), GFP_KERNEL);
3067         if (!pdata) {
3068                 dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
3069                 return -ENOMEM;
3070         }
3071
3072         if (of_property_read_bool(pdev->dev.of_node,
3073                                 "qcom,msm-pcm-low-latency")) {
3074
3075                 pdata->perf_mode = LOW_LATENCY_PCM_MODE;
3076                 rc = of_property_read_string(pdev->dev.of_node,
3077                         "qcom,latency-level", &latency_level);
3078                 if (!rc) {
3079                         if (!strcmp(latency_level, "ultra"))
3080                                 pdata->perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
3081                         else if (!strcmp(latency_level, "ull-pp"))
3082                                 pdata->perf_mode =
3083                                         ULL_POST_PROCESSING_PCM_MODE;
3084                 }
3085         } else {
3086                 pdata->perf_mode = LEGACY_PCM_MODE;
3087         }
3088
3089         if (of_property_read_bool(pdev->dev.of_node,
3090                                 "qcom,avs-version"))
3091                 pdata->avs_ver = true;
3092         else
3093                 pdata->avs_ver = false;
3094
3095         pr_debug("%s: avs_ver = %d\n", __func__, pdata->avs_ver);
3096
3097         dev_set_drvdata(&pdev->dev, pdata);
3098
3099         dev_dbg(&pdev->dev, "%s: dev name %s\n",
3100                                 __func__, dev_name(&pdev->dev));
3101         return snd_soc_register_platform(&pdev->dev,
3102                                    &msm_soc_platform);
3103 }
3104
3105 static int msm_pcm_remove(struct platform_device *pdev)
3106 {
3107         struct msm_plat_data *pdata;
3108
3109         pdata = dev_get_drvdata(&pdev->dev);
3110         kfree(pdata);
3111         snd_soc_unregister_platform(&pdev->dev);
3112         return 0;
3113 }
3114 static const struct of_device_id msm_pcm_dt_match[] = {
3115         {.compatible = "qcom,msm-pcm-dsp"},
3116         {}
3117 };
3118 MODULE_DEVICE_TABLE(of, msm_pcm_dt_match);
3119
3120 static struct platform_driver msm_pcm_driver = {
3121         .driver = {
3122                 .name = "msm-pcm-dsp",
3123                 .owner = THIS_MODULE,
3124                 .of_match_table = msm_pcm_dt_match,
3125         },
3126         .probe = msm_pcm_probe,
3127         .remove = msm_pcm_remove,
3128 };
3129
3130 static int __init msm_soc_platform_init(void)
3131 {
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);
3136
3137         return platform_driver_register(&msm_pcm_driver);
3138 }
3139 module_init(msm_soc_platform_init);
3140
3141 static void __exit msm_soc_platform_exit(void)
3142 {
3143         platform_driver_unregister(&msm_pcm_driver);
3144 }
3145 module_exit(msm_soc_platform_exit);
3146
3147 MODULE_DESCRIPTION("PCM module platform driver");
3148 MODULE_LICENSE("GPL v2");