blob: cf2f2640de34a0bb02de9859b34a583bd7a20890 [file] [log] [blame]
Sachin Mohan Gadag265d94d2018-01-04 11:04:00 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302 *
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/math64.h>
20#include <linux/wait.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/pcm.h>
27#include <sound/initval.h>
28#include <sound/control.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053029#include <sound/pcm_params.h>
30#include <sound/audio_effects.h>
31#include <asm/dma.h>
32#include <linux/dma-mapping.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053033#include <linux/msm_audio.h>
34
35#include <sound/timer.h>
36#include <sound/tlv.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053037#include <sound/compress_params.h>
38#include <sound/compress_offload.h>
39#include <sound/compress_driver.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053040
41#include <dsp/msm_audio_ion.h>
42#include <dsp/apr_audio-v2.h>
43#include <dsp/q6asm-v2.h>
Dieter Lueckingba7644d2018-09-28 15:09:32 +020044#include <dsp/q6core.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053045#include <dsp/msm-audio-effects-q6-v2.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053046#include "msm-pcm-routing-v2.h"
47#include "msm-qti-pp-config.h"
48
49#define DSP_PP_BUFFERING_IN_MSEC 25
50#define PARTIAL_DRAIN_ACK_EARLY_BY_MSEC 150
51#define MP3_OUTPUT_FRAME_SZ 1152
52#define AAC_OUTPUT_FRAME_SZ 1024
53#define AC3_OUTPUT_FRAME_SZ 1536
54#define EAC3_OUTPUT_FRAME_SZ 1536
55#define DSP_NUM_OUTPUT_FRAME_BUFFERED 2
56#define FLAC_BLK_SIZE_LIMIT 65535
57
58/* Timestamp mode payload offsets */
59#define CAPTURE_META_DATA_TS_OFFSET_LSW 6
60#define CAPTURE_META_DATA_TS_OFFSET_MSW 7
61
62/* decoder parameter length */
63#define DDP_DEC_MAX_NUM_PARAM 18
64
65/* Default values used if user space does not set */
66#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024)
67#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
68#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4)
69#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
70
71#define COMPRESSED_LR_VOL_MAX_STEPS 0x2000
72const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0,
73 COMPRESSED_LR_VOL_MAX_STEPS);
74
75/* Stream id switches between 1 and 2 */
76#define NEXT_STREAM_ID(stream_id) ((stream_id & 1) + 1)
77
78#define STREAM_ARRAY_INDEX(stream_id) (stream_id - 1)
79
80#define MAX_NUMBER_OF_STREAMS 2
81
82struct msm_compr_gapless_state {
83 bool set_next_stream_id;
84 int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
85 uint32_t initial_samples_drop;
86 uint32_t trailing_samples_drop;
87 uint32_t gapless_transition;
88 bool use_dsp_gapless_mode;
89 union snd_codec_options codec_options;
90};
91
92static unsigned int supported_sample_rates[] = {
93 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000,
94 88200, 96000, 128000, 144000, 176400, 192000, 352800, 384000, 2822400,
95 5644800
96};
97
98struct msm_compr_pdata {
99 struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX];
100 uint32_t volume[MSM_FRONTEND_DAI_MAX][2]; /* For both L & R */
101 struct msm_compr_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX];
102 bool use_dsp_gapless_mode;
103 bool use_legacy_api; /* indicates use older asm apis*/
104 struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX];
105 struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
Aditya Bavanari9deef912017-11-20 13:31:31 +0530106 bool is_in_use[MSM_FRONTEND_DAI_MAX];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530107};
108
109struct msm_compr_audio {
110 struct snd_compr_stream *cstream;
111 struct snd_compr_caps compr_cap;
112 struct snd_compr_codec_caps codec_caps;
113 struct snd_compr_params codec_param;
114 struct audio_client *audio_client;
115
116 uint32_t codec;
117 uint32_t compr_passthr;
118 void *buffer; /* virtual address */
119 phys_addr_t buffer_paddr; /* physical address */
120 uint32_t app_pointer;
121 uint32_t buffer_size;
122 uint32_t byte_offset;
123 uint64_t copied_total; /* bytes consumed by DSP */
124 uint64_t bytes_received; /* from userspace */
125 uint64_t bytes_sent; /* to DSP */
126
127 uint64_t received_total; /* bytes received from DSP */
128 uint64_t bytes_copied; /* to userspace */
129 uint64_t bytes_read; /* from DSP */
130 uint32_t bytes_read_offset; /* bytes read offset */
131
132 uint32_t ts_header_offset; /* holds the timestamp header offset */
133
134 int32_t first_buffer;
135 int32_t last_buffer;
136 int32_t partial_drain_delay;
137
138 uint16_t session_id;
139
140 uint32_t sample_rate;
141 uint32_t num_channels;
142
143 /*
144 * convention - commands coming from the same thread
145 * can use the common cmd_ack var. Others (e.g drain/EOS)
146 * must use separate vars to track command status.
147 */
148 uint32_t cmd_ack;
149 uint32_t cmd_interrupt;
150 uint32_t drain_ready;
151 uint32_t eos_ack;
152
153 uint32_t stream_available;
154 uint32_t next_stream;
155
156 uint32_t run_mode;
157 uint32_t start_delay_lsw;
158 uint32_t start_delay_msw;
159
160 uint64_t marker_timestamp;
161
162 struct msm_compr_gapless_state gapless_state;
163
164 atomic_t start;
165 atomic_t eos;
166 atomic_t drain;
167 atomic_t xrun;
168 atomic_t close;
169 atomic_t wait_on_close;
170 atomic_t error;
171
172 wait_queue_head_t eos_wait;
173 wait_queue_head_t drain_wait;
174 wait_queue_head_t close_wait;
175 wait_queue_head_t wait_for_stream_avail;
176
177 spinlock_t lock;
178};
179
180const u32 compr_codecs[] = {
181 SND_AUDIOCODEC_AC3, SND_AUDIOCODEC_EAC3, SND_AUDIOCODEC_DTS,
182 SND_AUDIOCODEC_DSD, SND_AUDIOCODEC_TRUEHD, SND_AUDIOCODEC_IEC61937};
183
184struct query_audio_effect {
185 uint32_t mod_id;
186 uint32_t parm_id;
187 uint32_t size;
188 uint32_t offset;
189 uint32_t device;
190};
191
192struct msm_compr_audio_effects {
193 struct bass_boost_params bass_boost;
194 struct pbe_params pbe;
195 struct virtualizer_params virtualizer;
196 struct reverb_params reverb;
197 struct eq_params equalizer;
198 struct soft_volume_params volume;
199 struct query_audio_effect query;
200};
201
202struct msm_compr_dec_params {
203 struct snd_dec_ddp ddp_params;
204};
205
206struct msm_compr_ch_map {
207 bool set_ch_map;
Dieter Lueckingba7644d2018-09-28 15:09:32 +0200208 char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530209};
210
211static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
212 struct msm_compr_dec_params *dec_params,
213 int stream_id);
214
215static int msm_compr_set_render_mode(struct msm_compr_audio *prtd,
216 uint32_t render_mode) {
217 int ret = -EINVAL;
218 struct audio_client *ac = prtd->audio_client;
219
220 pr_debug("%s, got render mode %u\n", __func__, render_mode);
221
222 if (render_mode == SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER) {
223 render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT;
224 } else if (render_mode == SNDRV_COMPRESS_RENDER_MODE_STC_MASTER) {
225 render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC;
226 prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY;
227 } else {
228 pr_err("%s, Invalid render mode %u\n", __func__,
229 render_mode);
230 ret = -EINVAL;
231 goto exit;
232 }
233
234 ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
235 if (ret) {
236 pr_err("%s, Render mode can't be set error %d\n", __func__,
237 ret);
238 }
239exit:
240 return ret;
241}
242
243static int msm_compr_set_clk_rec_mode(struct audio_client *ac,
244 uint32_t clk_rec_mode) {
245 int ret = -EINVAL;
246
247 pr_debug("%s, got clk rec mode %u\n", __func__, clk_rec_mode);
248
249 if (clk_rec_mode == SNDRV_COMPRESS_CLK_REC_MODE_NONE) {
250 clk_rec_mode = ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_NONE;
251 } else if (clk_rec_mode == SNDRV_COMPRESS_CLK_REC_MODE_AUTO) {
252 clk_rec_mode = ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_AUTO;
253 } else {
254 pr_err("%s, Invalid clk rec_mode mode %u\n", __func__,
255 clk_rec_mode);
256 ret = -EINVAL;
257 goto exit;
258 }
259
260 ret = q6asm_send_mtmx_strtr_clk_rec_mode(ac, clk_rec_mode);
261 if (ret) {
262 pr_err("%s, clk rec mode can't be set, error %d\n", __func__,
263 ret);
264 }
265
266exit:
267 return ret;
268}
269
270static int msm_compr_set_render_window(struct audio_client *ac,
271 uint32_t ws_lsw, uint32_t ws_msw,
272 uint32_t we_lsw, uint32_t we_msw)
273{
274 int ret = -EINVAL;
275 struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window;
276 uint32_t param_id;
277
278 pr_debug("%s, ws_lsw 0x%x ws_msw 0x%x we_lsw 0x%x we_ms 0x%x\n",
279 __func__, ws_lsw, ws_msw, we_lsw, we_msw);
280
281 memset(&asm_mtmx_strtr_window, 0,
282 sizeof(struct asm_session_mtmx_strtr_param_window_v2_t));
283 asm_mtmx_strtr_window.window_lsw = ws_lsw;
284 asm_mtmx_strtr_window.window_msw = ws_msw;
285 param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2;
286 ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window,
287 param_id);
288 if (ret) {
289 pr_err("%s, start window can't be set error %d\n", __func__,
290 ret);
291 goto exit;
292 }
293
294 asm_mtmx_strtr_window.window_lsw = we_lsw;
295 asm_mtmx_strtr_window.window_msw = we_msw;
296 param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2;
297 ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window,
298 param_id);
299 if (ret) {
300 pr_err("%s, end window can't be set error %d\n", __func__,
301 ret);
302 }
303
304exit:
305 return ret;
306}
307
308static int msm_compr_enable_adjust_session_clock(struct audio_client *ac,
309 bool enable)
310{
311 int ret;
312
313 pr_debug("%s, enable adjust_session %d\n", __func__, enable);
314
315 ret = q6asm_send_mtmx_strtr_enable_adjust_session_clock(ac, enable);
316 if (ret)
317 pr_err("%s, adjust session clock can't be set error %d\n",
318 __func__, ret);
319
320 return ret;
321}
322
323static int msm_compr_adjust_session_clock(struct audio_client *ac,
324 uint32_t adjust_session_lsw, uint32_t adjust_session_msw)
325{
326 int ret;
327
328 pr_debug("%s, adjust_session_time_msw 0x%x adjust_session_time_lsw 0x%x\n",
329 __func__, adjust_session_msw, adjust_session_lsw);
330
331 ret = q6asm_adjust_session_clock(ac,
332 adjust_session_lsw,
333 adjust_session_msw);
334 if (ret)
335 pr_err("%s, adjust session clock can't be set error %d\n",
336 __func__, ret);
337
338 return ret;
339}
340
341static int msm_compr_set_volume(struct snd_compr_stream *cstream,
342 uint32_t volume_l, uint32_t volume_r)
343{
344 struct msm_compr_audio *prtd;
345 int rc = 0;
346 uint32_t avg_vol, gain_list[VOLUME_CONTROL_MAX_CHANNELS];
347 uint32_t num_channels;
348 struct snd_soc_pcm_runtime *rtd;
349 struct msm_compr_pdata *pdata;
350 bool use_default = true;
351 u8 *chmap = NULL;
352
353 pr_debug("%s: volume_l %d volume_r %d\n",
354 __func__, volume_l, volume_r);
355 if (!cstream || !cstream->runtime) {
356 pr_err("%s: session not active\n", __func__);
357 return -EPERM;
358 }
359 rtd = cstream->private_data;
360 prtd = cstream->runtime->private_data;
361
362 if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) {
363 pr_err("%s: invalid rtd, prtd or audio client", __func__);
364 return rc;
365 }
366 pdata = snd_soc_platform_get_drvdata(rtd->platform);
367
368 if (prtd->compr_passthr != LEGACY_PCM) {
369 pr_debug("%s: No volume config for passthrough %d\n",
370 __func__, prtd->compr_passthr);
371 return rc;
372 }
373
374 use_default = !(pdata->ch_map[rtd->dai_link->id]->set_ch_map);
375 chmap = pdata->ch_map[rtd->dai_link->id]->channel_map;
376 num_channels = prtd->num_channels;
377
378 if (prtd->num_channels > 2) {
379 /*
380 * Currently the left and right gains are averaged an applied
381 * to all channels. This might not be desirable. But currently,
382 * there exists no API in userspace to send a list of gains for
383 * each channel either. If such an API does become available,
384 * the mixer control must be updated to accept more than 2
385 * channel gains.
386 *
387 */
388 avg_vol = (volume_l + volume_r) / 2;
389 rc = q6asm_set_volume(prtd->audio_client, avg_vol);
390 } else {
391 gain_list[0] = volume_l;
392 gain_list[1] = volume_r;
yidongh98526ef2017-09-05 17:57:55 +0800393 gain_list[2] = volume_l;
394 num_channels = 3;
395 use_default = true;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530396 rc = q6asm_set_multich_gain(prtd->audio_client, num_channels,
397 gain_list, chmap, use_default);
398 }
399
400 if (rc < 0)
401 pr_err("%s: Send vol gain command failed rc=%d\n",
402 __func__, rc);
403
404 return rc;
405}
406
407static int msm_compr_send_ddp_cfg(struct audio_client *ac,
408 struct snd_dec_ddp *ddp,
409 int stream_id)
410{
411 int i, rc;
412
413 pr_debug("%s\n", __func__);
414 for (i = 0; i < ddp->params_length; i++) {
415 rc = q6asm_ds1_set_stream_endp_params(ac, ddp->params_id[i],
416 ddp->params_value[i],
417 stream_id);
418 if (rc) {
419 pr_err("sending params_id: %d failed\n",
420 ddp->params_id[i]);
421 return rc;
422 }
423 }
424 return 0;
425}
426
427static int msm_compr_send_buffer(struct msm_compr_audio *prtd)
428{
429 int buffer_length;
430 uint64_t bytes_available;
431 struct audio_aio_write_param param;
432 struct snd_codec_metadata *buff_addr;
433
434 if (!atomic_read(&prtd->start)) {
435 pr_err("%s: stream is not in started state\n", __func__);
436 return -EINVAL;
437 }
438
439
440 if (atomic_read(&prtd->xrun)) {
441 WARN(1, "%s called while xrun is true", __func__);
442 return -EPERM;
443 }
444
445 pr_debug("%s: bytes_received = %llu copied_total = %llu\n",
446 __func__, prtd->bytes_received, prtd->copied_total);
447 if (prtd->first_buffer && prtd->gapless_state.use_dsp_gapless_mode &&
448 prtd->compr_passthr == LEGACY_PCM)
449 q6asm_stream_send_meta_data(prtd->audio_client,
450 prtd->audio_client->stream_id,
451 prtd->gapless_state.initial_samples_drop,
452 prtd->gapless_state.trailing_samples_drop);
453
454 buffer_length = prtd->codec_param.buffer.fragment_size;
455 bytes_available = prtd->bytes_received - prtd->copied_total;
456 if (bytes_available < prtd->codec_param.buffer.fragment_size)
457 buffer_length = bytes_available;
458
459 if (prtd->byte_offset + buffer_length > prtd->buffer_size) {
460 buffer_length = (prtd->buffer_size - prtd->byte_offset);
461 pr_debug("%s: wrap around situation, send partial data %d now",
462 __func__, buffer_length);
463 }
464
465 if (buffer_length) {
466 param.paddr = prtd->buffer_paddr + prtd->byte_offset;
467 WARN(prtd->byte_offset % 32 != 0, "offset %x not multiple of 32\n",
468 prtd->byte_offset);
469 } else {
470 param.paddr = prtd->buffer_paddr;
471 }
472 param.len = buffer_length;
473 if (prtd->ts_header_offset) {
474 buff_addr = (struct snd_codec_metadata *)
475 (prtd->buffer + prtd->byte_offset);
476 param.len = buff_addr->length;
477 param.msw_ts = (uint32_t)
478 ((buff_addr->timestamp & 0xFFFFFFFF00000000LL) >> 32);
479 param.lsw_ts = (uint32_t) (buff_addr->timestamp & 0xFFFFFFFFLL);
480 param.paddr += prtd->ts_header_offset;
481 param.flags = SET_TIMESTAMP;
482 param.metadata_len = prtd->ts_header_offset;
483 } else {
484 param.msw_ts = 0;
485 param.lsw_ts = 0;
486 param.flags = NO_TIMESTAMP;
487 param.metadata_len = 0;
488 }
489 param.uid = buffer_length;
490 param.last_buffer = prtd->last_buffer;
491
492 pr_debug("%s: sending %d bytes to DSP byte_offset = %d\n",
493 __func__, param.len, prtd->byte_offset);
494 if (q6asm_async_write(prtd->audio_client, &param) < 0) {
495 pr_err("%s:q6asm_async_write failed\n", __func__);
496 } else {
497 prtd->bytes_sent += buffer_length;
498 if (prtd->first_buffer)
499 prtd->first_buffer = 0;
500 }
501
502 return 0;
503}
504
505static int msm_compr_read_buffer(struct msm_compr_audio *prtd)
506{
507 int buffer_length;
508 uint64_t bytes_available;
509 uint64_t buffer_sent;
510 struct audio_aio_read_param param;
511 int ret;
512
513 if (!atomic_read(&prtd->start)) {
514 pr_err("%s: stream is not in started state\n", __func__);
515 return -EINVAL;
516 }
517
518 buffer_length = prtd->codec_param.buffer.fragment_size -
519 prtd->ts_header_offset;
520 bytes_available = prtd->received_total - prtd->bytes_copied;
521 buffer_sent = prtd->bytes_read - prtd->bytes_copied;
522 if (buffer_sent + buffer_length + prtd->ts_header_offset
523 > prtd->buffer_size) {
524 pr_debug(" %s : Buffer is Full bytes_available: %llu\n",
525 __func__, bytes_available);
526 return 0;
527 }
528
529 memset(&param, 0x0, sizeof(struct audio_aio_read_param));
530 param.paddr = prtd->buffer_paddr + prtd->bytes_read_offset +
531 prtd->ts_header_offset;
532 param.len = buffer_length;
533 param.uid = buffer_length;
534 param.flags = prtd->codec_param.codec.flags;
535
536 pr_debug("%s: reading %d bytes from DSP byte_offset = %llu\n",
537 __func__, buffer_length, prtd->bytes_read);
538 ret = q6asm_async_read(prtd->audio_client, &param);
539 if (ret < 0) {
540 pr_err("%s: q6asm_async_read failed - %d\n",
541 __func__, ret);
542 return ret;
543 }
Sachin Mohan Gadag3a52de72018-07-05 15:48:12 +0530544 prtd->bytes_read += buffer_length + prtd->ts_header_offset;
Vikram Panduranga40b0ec62018-01-10 18:04:54 -0800545 prtd->bytes_read_offset += buffer_length + prtd->ts_header_offset;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530546 if (prtd->bytes_read_offset >= prtd->buffer_size)
547 prtd->bytes_read_offset -= prtd->buffer_size;
548
549 return 0;
550}
551
552static void compr_event_handler(uint32_t opcode,
553 uint32_t token, uint32_t *payload, void *priv)
554{
555 struct msm_compr_audio *prtd = priv;
556 struct snd_compr_stream *cstream;
557 struct audio_client *ac;
558 uint32_t chan_mode = 0;
559 uint32_t sample_rate = 0;
560 uint64_t bytes_available;
561 int stream_id;
562 uint32_t stream_index;
563 unsigned long flags;
564 uint64_t read_size;
565 uint32_t *buff_addr;
566 struct snd_soc_pcm_runtime *rtd;
567 int ret = 0;
568
569 if (!prtd) {
570 pr_err("%s: prtd is NULL\n", __func__);
571 return;
572 }
573 cstream = prtd->cstream;
574 if (!cstream) {
575 pr_err("%s: cstream is NULL\n", __func__);
576 return;
577 }
578
579 ac = prtd->audio_client;
580
581 /*
582 * Token for rest of the compressed commands use to set
583 * session id, stream id, dir etc.
584 */
585 stream_id = q6asm_get_stream_id_from_token(token);
586
587 pr_debug("%s opcode =%08x\n", __func__, opcode);
588 switch (opcode) {
589 case ASM_DATA_EVENT_WRITE_DONE_V2:
590 spin_lock_irqsave(&prtd->lock, flags);
591
592 if (payload[3]) {
593 pr_err("%s: WRITE FAILED w/ err 0x%x !, paddr 0x%x, byte_offset=%d,copied_total=%llu,token=%d\n",
594 __func__,
595 payload[3],
596 payload[0],
597 prtd->byte_offset,
598 prtd->copied_total, token);
599
600 if (atomic_cmpxchg(&prtd->drain, 1, 0) &&
601 prtd->last_buffer) {
602 pr_debug("%s: wake up on drain\n", __func__);
603 prtd->drain_ready = 1;
604 wake_up(&prtd->drain_wait);
605 prtd->last_buffer = 0;
606 } else {
607 atomic_set(&prtd->start, 0);
608 }
609 } else {
610 pr_debug("ASM_DATA_EVENT_WRITE_DONE_V2 offset %d, length %d\n",
611 prtd->byte_offset, token);
612 }
613
614 /*
615 * Token for WRITE command represents the amount of data
616 * written to ADSP in the last write, update offset and
617 * total copied data accordingly.
618 */
619 if (prtd->ts_header_offset) {
620 /* Always assume that the data will be sent to DSP on
621 * frame boundary.
622 * i.e, one frame of userspace write will result in
623 * one kernel write to DSP. This is needed as
624 * timestamp will be sent per frame.
625 */
626 prtd->byte_offset +=
627 prtd->codec_param.buffer.fragment_size;
628 prtd->copied_total +=
629 prtd->codec_param.buffer.fragment_size;
630 } else {
631 prtd->byte_offset += token;
632 prtd->copied_total += token;
633 }
634 if (prtd->byte_offset >= prtd->buffer_size)
635 prtd->byte_offset -= prtd->buffer_size;
636
637 snd_compr_fragment_elapsed(cstream);
638
639 if (!atomic_read(&prtd->start)) {
640 /* Writes must be restarted from _copy() */
641 pr_debug("write_done received while not started, treat as xrun");
642 atomic_set(&prtd->xrun, 1);
643 spin_unlock_irqrestore(&prtd->lock, flags);
644 break;
645 }
646
647 bytes_available = prtd->bytes_received - prtd->copied_total;
648 if (bytes_available < cstream->runtime->fragment_size) {
649 pr_debug("WRITE_DONE Insufficient data to send. break out\n");
650 atomic_set(&prtd->xrun, 1);
651
652 if (prtd->last_buffer)
653 prtd->last_buffer = 0;
654 if (atomic_read(&prtd->drain)) {
655 pr_debug("wake up on drain\n");
656 prtd->drain_ready = 1;
657 wake_up(&prtd->drain_wait);
658 atomic_set(&prtd->drain, 0);
659 }
660 } else if ((bytes_available == cstream->runtime->fragment_size)
661 && atomic_read(&prtd->drain)) {
662 prtd->last_buffer = 1;
663 msm_compr_send_buffer(prtd);
664 prtd->last_buffer = 0;
665 } else
666 msm_compr_send_buffer(prtd);
667
668 spin_unlock_irqrestore(&prtd->lock, flags);
669 break;
670
671 case ASM_DATA_EVENT_READ_DONE_V2:
672 spin_lock_irqsave(&prtd->lock, flags);
673
674 pr_debug("ASM_DATA_EVENT_READ_DONE_V2 offset %d, length %d\n",
675 prtd->byte_offset, payload[4]);
676
677 if (prtd->ts_header_offset) {
678 /* Update the header for received buffer */
679 buff_addr = prtd->buffer + prtd->byte_offset;
680 /* Write the length of the buffer */
681 *buff_addr = prtd->codec_param.buffer.fragment_size
682 - prtd->ts_header_offset;
683 buff_addr++;
684 /* Write the offset */
685 *buff_addr = prtd->ts_header_offset;
686 buff_addr++;
687 /* Write the TS LSW */
688 *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_LSW];
689 buff_addr++;
690 /* Write the TS MSW */
691 *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_MSW];
692 }
693 /* Always assume read_size is same as fragment_size */
694 read_size = prtd->codec_param.buffer.fragment_size;
695 prtd->byte_offset += read_size;
696 prtd->received_total += read_size;
697 if (prtd->byte_offset >= prtd->buffer_size)
698 prtd->byte_offset -= prtd->buffer_size;
699
700 snd_compr_fragment_elapsed(cstream);
701
702 if (!atomic_read(&prtd->start)) {
703 pr_debug("read_done received while not started, treat as xrun");
704 atomic_set(&prtd->xrun, 1);
705 spin_unlock_irqrestore(&prtd->lock, flags);
706 break;
707 }
708 msm_compr_read_buffer(prtd);
709
710 spin_unlock_irqrestore(&prtd->lock, flags);
711 break;
712
713 case ASM_DATA_EVENT_RENDERED_EOS:
714 spin_lock_irqsave(&prtd->lock, flags);
715 pr_debug("%s: ASM_DATA_CMDRSP_EOS token 0x%x,stream id %d\n",
716 __func__, token, stream_id);
717 if (atomic_read(&prtd->eos) &&
718 !prtd->gapless_state.set_next_stream_id) {
719 pr_debug("ASM_DATA_CMDRSP_EOS wake up\n");
720 prtd->eos_ack = 1;
721 wake_up(&prtd->eos_wait);
722 }
723 atomic_set(&prtd->eos, 0);
724 stream_index = STREAM_ARRAY_INDEX(stream_id);
725 if (stream_index >= MAX_NUMBER_OF_STREAMS ||
726 stream_index < 0) {
727 pr_err("%s: Invalid stream index %d", __func__,
728 stream_index);
729 spin_unlock_irqrestore(&prtd->lock, flags);
730 break;
731 }
732
733 if (prtd->gapless_state.set_next_stream_id &&
734 prtd->gapless_state.stream_opened[stream_index]) {
735 pr_debug("%s: CMD_CLOSE stream_id %d\n",
736 __func__, stream_id);
737 q6asm_stream_cmd_nowait(ac, CMD_CLOSE, stream_id);
738 atomic_set(&prtd->close, 1);
739 prtd->gapless_state.stream_opened[stream_index] = 0;
740 prtd->gapless_state.set_next_stream_id = false;
741 }
742 if (prtd->gapless_state.gapless_transition)
743 prtd->gapless_state.gapless_transition = 0;
744 spin_unlock_irqrestore(&prtd->lock, flags);
745 break;
746 case ASM_STREAM_PP_EVENT:
747 case ASM_STREAM_CMD_ENCDEC_EVENTS:
748 pr_debug("%s: ASM_STREAM_EVENT(0x%x)\n", __func__, opcode);
749 rtd = cstream->private_data;
750 if (!rtd) {
751 pr_err("%s: rtd is NULL\n", __func__);
752 return;
753 }
754
755 ret = msm_adsp_inform_mixer_ctl(rtd, payload);
756 if (ret) {
757 pr_err("%s: failed to inform mixer ctrl. err = %d\n",
758 __func__, ret);
759 return;
760 }
761 break;
762 case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
763 case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: {
764 pr_debug("ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY\n");
765 chan_mode = payload[1] >> 16;
766 sample_rate = payload[2] >> 16;
767 if (prtd && (chan_mode != prtd->num_channels ||
768 sample_rate != prtd->sample_rate)) {
769 prtd->num_channels = chan_mode;
770 prtd->sample_rate = sample_rate;
771 }
772 }
773 /* Fallthrough here */
774 case APR_BASIC_RSP_RESULT: {
775 switch (payload[0]) {
776 case ASM_SESSION_CMD_RUN_V2:
777 /* check if the first buffer need to be sent to DSP */
778 pr_debug("ASM_SESSION_CMD_RUN_V2\n");
779
780 /* FIXME: A state is a better way, dealing with this */
781 spin_lock_irqsave(&prtd->lock, flags);
782
783 if (cstream->direction == SND_COMPRESS_CAPTURE) {
784 atomic_set(&prtd->start, 1);
785 msm_compr_read_buffer(prtd);
786 spin_unlock_irqrestore(&prtd->lock, flags);
787 break;
788 }
789
790 if (!prtd->bytes_sent) {
791 bytes_available = prtd->bytes_received -
792 prtd->copied_total;
793 if (bytes_available <
794 cstream->runtime->fragment_size) {
795 pr_debug("CMD_RUN_V2 Insufficient data to send. break out\n");
796 atomic_set(&prtd->xrun, 1);
797 } else {
798 msm_compr_send_buffer(prtd);
799 }
800 }
801
802 /*
803 * The condition below ensures playback finishes in the
804 * follow cornercase
805 * WRITE(last buffer)
806 * WAIT_FOR_DRAIN
807 * PAUSE
808 * WRITE_DONE(X)
809 * RESUME
810 */
811 if ((prtd->copied_total == prtd->bytes_sent) &&
812 atomic_read(&prtd->drain)) {
813 pr_debug("RUN ack, wake up & continue pending drain\n");
814
815 if (prtd->last_buffer)
816 prtd->last_buffer = 0;
817
818 prtd->drain_ready = 1;
819 wake_up(&prtd->drain_wait);
820 atomic_set(&prtd->drain, 0);
821 }
822
823 spin_unlock_irqrestore(&prtd->lock, flags);
824 break;
825 case ASM_STREAM_CMD_FLUSH:
826 pr_debug("%s: ASM_STREAM_CMD_FLUSH:", __func__);
827 pr_debug("token 0x%x, stream id %d\n", token,
828 stream_id);
829 prtd->cmd_ack = 1;
830 break;
831 case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
832 pr_debug("%s: ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:",
833 __func__);
834 pr_debug("token 0x%x, stream id = %d\n", token,
835 stream_id);
836 break;
837 case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
838 pr_debug("%s: ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:",
839 __func__);
840 pr_debug("token = 0x%x, stream id = %d\n", token,
841 stream_id);
842 break;
843 case ASM_STREAM_CMD_CLOSE:
844 pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__);
845 pr_debug("token 0x%x, stream id %d\n", token,
846 stream_id);
847 /*
848 * wakeup wait for stream avail on stream 3
849 * after stream 1 ends.
850 */
851 if (prtd->next_stream) {
852 pr_debug("%s:CLOSE:wakeup wait for stream\n",
853 __func__);
854 prtd->stream_available = 1;
855 wake_up(&prtd->wait_for_stream_avail);
856 prtd->next_stream = 0;
857 }
858 if (atomic_read(&prtd->close) &&
859 atomic_read(&prtd->wait_on_close)) {
860 prtd->cmd_ack = 1;
861 wake_up(&prtd->close_wait);
862 }
863 atomic_set(&prtd->close, 0);
864 break;
865 case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
866 pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:",
867 __func__);
868 break;
869 default:
870 break;
871 }
872 break;
873 }
874 case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
875 pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3\n",
876 __func__);
877 break;
878 case RESET_EVENTS:
879 pr_err("%s: Received reset events CB, move to error state",
880 __func__);
881 spin_lock_irqsave(&prtd->lock, flags);
882 /*
883 * Since ADSP is down, let this driver pretend that it copied
884 * all the bytes received, so that next write will be triggered
885 */
886 prtd->copied_total = prtd->bytes_received;
887 snd_compr_fragment_elapsed(cstream);
888 atomic_set(&prtd->error, 1);
889 wake_up(&prtd->drain_wait);
890 if (atomic_cmpxchg(&prtd->eos, 1, 0)) {
891 pr_debug("%s:unblock eos wait queues", __func__);
892 wake_up(&prtd->eos_wait);
893 }
894 spin_unlock_irqrestore(&prtd->lock, flags);
895 break;
896 default:
897 pr_debug("%s: Not Supported Event opcode[0x%x]\n",
898 __func__, opcode);
899 break;
900 }
901}
902
903static int msm_compr_get_partial_drain_delay(int frame_sz, int sample_rate)
904{
905 int delay_time_ms = 0;
906
907 delay_time_ms = ((DSP_NUM_OUTPUT_FRAME_BUFFERED * frame_sz * 1000) /
908 sample_rate) + DSP_PP_BUFFERING_IN_MSEC;
909 delay_time_ms = delay_time_ms > PARTIAL_DRAIN_ACK_EARLY_BY_MSEC ?
910 delay_time_ms - PARTIAL_DRAIN_ACK_EARLY_BY_MSEC : 0;
911
912 pr_debug("%s: frame_sz %d, sample_rate %d, partial drain delay %d\n",
913 __func__, frame_sz, sample_rate, delay_time_ms);
914 return delay_time_ms;
915}
916
917static void populate_codec_list(struct msm_compr_audio *prtd)
918{
919 pr_debug("%s\n", __func__);
920 prtd->compr_cap.direction = SND_COMPRESS_PLAYBACK;
921 prtd->compr_cap.min_fragment_size =
922 COMPR_PLAYBACK_MIN_FRAGMENT_SIZE;
923 prtd->compr_cap.max_fragment_size =
924 COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
925 prtd->compr_cap.min_fragments =
926 COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
927 prtd->compr_cap.max_fragments =
928 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
929 prtd->compr_cap.num_codecs = 17;
930 prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
931 prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
932 prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
933 prtd->compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3;
934 prtd->compr_cap.codecs[4] = SND_AUDIOCODEC_MP2;
935 prtd->compr_cap.codecs[5] = SND_AUDIOCODEC_PCM;
936 prtd->compr_cap.codecs[6] = SND_AUDIOCODEC_WMA;
937 prtd->compr_cap.codecs[7] = SND_AUDIOCODEC_WMA_PRO;
938 prtd->compr_cap.codecs[8] = SND_AUDIOCODEC_FLAC;
939 prtd->compr_cap.codecs[9] = SND_AUDIOCODEC_VORBIS;
940 prtd->compr_cap.codecs[10] = SND_AUDIOCODEC_ALAC;
941 prtd->compr_cap.codecs[11] = SND_AUDIOCODEC_APE;
942 prtd->compr_cap.codecs[12] = SND_AUDIOCODEC_DTS;
943 prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD;
944 prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX;
945 prtd->compr_cap.codecs[15] = SND_AUDIOCODEC_TRUEHD;
946 prtd->compr_cap.codecs[16] = SND_AUDIOCODEC_IEC61937;
947}
948
949static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
950 int stream_id,
951 bool use_gapless_codec_options)
952{
953 struct snd_compr_runtime *runtime = cstream->runtime;
954 struct msm_compr_audio *prtd = runtime->private_data;
955 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
956 struct msm_compr_pdata *pdata =
957 snd_soc_platform_get_drvdata(rtd->platform);
958 struct asm_aac_cfg aac_cfg;
959 struct asm_wma_cfg wma_cfg;
960 struct asm_wmapro_cfg wma_pro_cfg;
961 struct asm_flac_cfg flac_cfg;
962 struct asm_vorbis_cfg vorbis_cfg;
963 struct asm_alac_cfg alac_cfg;
964 struct asm_ape_cfg ape_cfg;
965 struct asm_dsd_cfg dsd_cfg;
966 struct aptx_dec_bt_addr_cfg aptx_cfg;
967 union snd_codec_options *codec_options;
968
969 int ret = 0;
970 uint16_t bit_width;
971 bool use_default_chmap = true;
972 char *chmap = NULL;
973 uint16_t sample_word_size;
974
975 pr_debug("%s: use_gapless_codec_options %d\n",
976 __func__, use_gapless_codec_options);
977
978 if (use_gapless_codec_options)
979 codec_options = &(prtd->gapless_state.codec_options);
980 else
981 codec_options = &(prtd->codec_param.codec.options);
982
983 if (!codec_options) {
984 pr_err("%s: codec_options is NULL\n", __func__);
985 return -EINVAL;
986 }
987
988 switch (prtd->codec) {
989 case FORMAT_LINEAR_PCM:
990 pr_debug("SND_AUDIOCODEC_PCM\n");
991 if (pdata->ch_map[rtd->dai_link->id]) {
992 use_default_chmap =
993 !(pdata->ch_map[rtd->dai_link->id]->set_ch_map);
994 chmap =
995 pdata->ch_map[rtd->dai_link->id]->channel_map;
996 }
997
998 switch (prtd->codec_param.codec.format) {
999 case SNDRV_PCM_FORMAT_S32_LE:
1000 bit_width = 32;
1001 sample_word_size = 32;
1002 break;
1003 case SNDRV_PCM_FORMAT_S24_LE:
1004 bit_width = 24;
1005 sample_word_size = 32;
1006 break;
1007 case SNDRV_PCM_FORMAT_S24_3LE:
1008 bit_width = 24;
1009 sample_word_size = 24;
1010 break;
1011 case SNDRV_PCM_FORMAT_S16_LE:
1012 default:
1013 bit_width = 16;
1014 sample_word_size = 16;
1015 break;
1016 }
Dieter Lueckingba7644d2018-09-28 15:09:32 +02001017
1018 if (q6core_get_avcs_api_version_per_service(
1019 APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
1020 ADSP_ASM_API_VERSION_V2) {
1021 ret = q6asm_media_format_block_pcm_format_support_v5(
1022 prtd->audio_client,
1023 prtd->sample_rate,
1024 prtd->num_channels,
1025 bit_width, stream_id,
1026 use_default_chmap,
1027 chmap,
1028 sample_word_size,
1029 ASM_LITTLE_ENDIAN,
1030 DEFAULT_QF);
1031 } else {
1032 ret = q6asm_media_format_block_pcm_format_support_v4(
1033 prtd->audio_client,
1034 prtd->sample_rate,
1035 prtd->num_channels,
1036 bit_width, stream_id,
1037 use_default_chmap,
1038 chmap,
1039 sample_word_size,
1040 ASM_LITTLE_ENDIAN,
1041 DEFAULT_QF);
1042 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301043 if (ret < 0)
1044 pr_err("%s: CMD Format block failed\n", __func__);
1045
1046 break;
1047 case FORMAT_MP3:
1048 pr_debug("SND_AUDIOCODEC_MP3\n");
1049 /* no media format block needed */
1050 break;
1051 case FORMAT_MPEG4_AAC:
1052 pr_debug("SND_AUDIOCODEC_AAC\n");
1053 memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg));
1054 aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
1055 if (prtd->codec_param.codec.format ==
1056 SND_AUDIOSTREAMFORMAT_MP4ADTS)
1057 aac_cfg.format = 0x0;
1058 else if (prtd->codec_param.codec.format ==
1059 SND_AUDIOSTREAMFORMAT_MP4LATM)
1060 aac_cfg.format = 0x04;
1061 else
1062 aac_cfg.format = 0x03;
1063 aac_cfg.ch_cfg = prtd->num_channels;
1064 aac_cfg.sample_rate = prtd->sample_rate;
1065 ret = q6asm_stream_media_format_block_aac(prtd->audio_client,
1066 &aac_cfg, stream_id);
1067 if (ret < 0)
1068 pr_err("%s: CMD Format block failed\n", __func__);
1069 break;
1070 case FORMAT_AC3:
1071 pr_debug("SND_AUDIOCODEC_AC3\n");
1072 break;
1073 case FORMAT_EAC3:
1074 pr_debug("SND_AUDIOCODEC_EAC3\n");
1075 break;
1076 case FORMAT_WMA_V9:
1077 pr_debug("SND_AUDIOCODEC_WMA\n");
1078 memset(&wma_cfg, 0x0, sizeof(struct asm_wma_cfg));
1079 wma_cfg.format_tag = prtd->codec_param.codec.format;
1080 wma_cfg.ch_cfg = prtd->codec_param.codec.ch_in;
1081 wma_cfg.sample_rate = prtd->sample_rate;
1082 wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8;
1083 wma_cfg.block_align = codec_options->wma.super_block_align;
1084 wma_cfg.valid_bits_per_sample =
1085 codec_options->wma.bits_per_sample;
1086 wma_cfg.ch_mask = codec_options->wma.channelmask;
1087 wma_cfg.encode_opt = codec_options->wma.encodeopt;
1088 ret = q6asm_media_format_block_wma(prtd->audio_client,
1089 &wma_cfg, stream_id);
1090 if (ret < 0)
1091 pr_err("%s: CMD Format block failed\n", __func__);
1092 break;
1093 case FORMAT_WMA_V10PRO:
1094 pr_debug("SND_AUDIOCODEC_WMA_PRO\n");
1095 memset(&wma_pro_cfg, 0x0, sizeof(struct asm_wmapro_cfg));
1096 wma_pro_cfg.format_tag = prtd->codec_param.codec.format;
1097 wma_pro_cfg.ch_cfg = prtd->codec_param.codec.ch_in;
1098 wma_pro_cfg.sample_rate = prtd->sample_rate;
1099 wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8;
1100 wma_pro_cfg.block_align = codec_options->wma.super_block_align;
1101 wma_pro_cfg.valid_bits_per_sample =
1102 codec_options->wma.bits_per_sample;
1103 wma_pro_cfg.ch_mask = codec_options->wma.channelmask;
1104 wma_pro_cfg.encode_opt = codec_options->wma.encodeopt;
1105 wma_pro_cfg.adv_encode_opt = codec_options->wma.encodeopt1;
1106 wma_pro_cfg.adv_encode_opt2 = codec_options->wma.encodeopt2;
1107 ret = q6asm_media_format_block_wmapro(prtd->audio_client,
1108 &wma_pro_cfg, stream_id);
1109 if (ret < 0)
1110 pr_err("%s: CMD Format block failed\n", __func__);
1111 break;
1112 case FORMAT_MP2:
1113 pr_debug("%s: SND_AUDIOCODEC_MP2\n", __func__);
1114 break;
1115 case FORMAT_FLAC:
1116 pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
1117 memset(&flac_cfg, 0x0, sizeof(struct asm_flac_cfg));
1118 flac_cfg.ch_cfg = prtd->num_channels;
1119 flac_cfg.sample_rate = prtd->sample_rate;
1120 flac_cfg.stream_info_present = 1;
1121 flac_cfg.sample_size = codec_options->flac_dec.sample_size;
1122 flac_cfg.min_blk_size = codec_options->flac_dec.min_blk_size;
1123 flac_cfg.max_blk_size = codec_options->flac_dec.max_blk_size;
1124 flac_cfg.max_frame_size =
1125 codec_options->flac_dec.max_frame_size;
1126 flac_cfg.min_frame_size =
1127 codec_options->flac_dec.min_frame_size;
1128
1129 ret = q6asm_stream_media_format_block_flac(prtd->audio_client,
1130 &flac_cfg, stream_id);
1131 if (ret < 0)
1132 pr_err("%s: CMD Format block failed ret %d\n",
1133 __func__, ret);
1134
1135 break;
1136 case FORMAT_VORBIS:
1137 pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__);
1138 memset(&vorbis_cfg, 0x0, sizeof(struct asm_vorbis_cfg));
1139 vorbis_cfg.bit_stream_fmt =
1140 codec_options->vorbis_dec.bit_stream_fmt;
1141
1142 ret = q6asm_stream_media_format_block_vorbis(
1143 prtd->audio_client, &vorbis_cfg,
1144 stream_id);
1145 if (ret < 0)
1146 pr_err("%s: CMD Format block failed ret %d\n",
1147 __func__, ret);
1148
1149 break;
1150 case FORMAT_ALAC:
1151 pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__);
1152 memset(&alac_cfg, 0x0, sizeof(struct asm_alac_cfg));
1153 alac_cfg.num_channels = prtd->num_channels;
1154 alac_cfg.sample_rate = prtd->sample_rate;
1155 alac_cfg.frame_length = codec_options->alac.frame_length;
1156 alac_cfg.compatible_version =
1157 codec_options->alac.compatible_version;
1158 alac_cfg.bit_depth = codec_options->alac.bit_depth;
1159 alac_cfg.pb = codec_options->alac.pb;
1160 alac_cfg.mb = codec_options->alac.mb;
1161 alac_cfg.kb = codec_options->alac.kb;
1162 alac_cfg.max_run = codec_options->alac.max_run;
1163 alac_cfg.max_frame_bytes = codec_options->alac.max_frame_bytes;
1164 alac_cfg.avg_bit_rate = codec_options->alac.avg_bit_rate;
1165 alac_cfg.channel_layout_tag =
1166 codec_options->alac.channel_layout_tag;
1167
1168 ret = q6asm_media_format_block_alac(prtd->audio_client,
1169 &alac_cfg, stream_id);
1170 if (ret < 0)
1171 pr_err("%s: CMD Format block failed ret %d\n",
1172 __func__, ret);
1173 break;
1174 case FORMAT_APE:
1175 pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__);
1176 memset(&ape_cfg, 0x0, sizeof(struct asm_ape_cfg));
1177 ape_cfg.num_channels = prtd->num_channels;
1178 ape_cfg.sample_rate = prtd->sample_rate;
1179 ape_cfg.compatible_version =
1180 codec_options->ape.compatible_version;
1181 ape_cfg.compression_level =
1182 codec_options->ape.compression_level;
1183 ape_cfg.format_flags = codec_options->ape.format_flags;
1184 ape_cfg.blocks_per_frame = codec_options->ape.blocks_per_frame;
1185 ape_cfg.final_frame_blocks =
1186 codec_options->ape.final_frame_blocks;
1187 ape_cfg.total_frames = codec_options->ape.total_frames;
1188 ape_cfg.bits_per_sample = codec_options->ape.bits_per_sample;
1189 ape_cfg.seek_table_present =
1190 codec_options->ape.seek_table_present;
1191
1192 ret = q6asm_media_format_block_ape(prtd->audio_client,
1193 &ape_cfg, stream_id);
1194
1195 if (ret < 0)
1196 pr_err("%s: CMD Format block failed ret %d\n",
1197 __func__, ret);
1198 break;
1199 case FORMAT_DTS:
1200 pr_debug("SND_AUDIOCODEC_DTS\n");
1201 /* no media format block needed */
1202 break;
1203 case FORMAT_DSD:
1204 pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
1205 memset(&dsd_cfg, 0x0, sizeof(struct asm_dsd_cfg));
1206 dsd_cfg.num_channels = prtd->num_channels;
1207 dsd_cfg.dsd_data_rate = prtd->sample_rate;
1208 dsd_cfg.num_version = 0;
1209 dsd_cfg.is_bitwise_big_endian = 1;
1210 dsd_cfg.dsd_channel_block_size = 1;
1211 ret = q6asm_media_format_block_dsd(prtd->audio_client,
1212 &dsd_cfg, stream_id);
1213 if (ret < 0)
1214 pr_err("%s: CMD DSD Format block failed ret %d\n",
1215 __func__, ret);
1216 break;
1217 case FORMAT_TRUEHD:
1218 pr_debug("SND_AUDIOCODEC_TRUEHD\n");
1219 /* no media format block needed */
1220 break;
1221 case FORMAT_IEC61937:
1222 pr_debug("SND_AUDIOCODEC_IEC61937\n");
1223 ret = q6asm_media_format_block_iec(prtd->audio_client,
1224 prtd->sample_rate,
1225 prtd->num_channels);
1226 if (ret < 0)
1227 pr_err("%s: CMD IEC61937 Format block failed ret %d\n",
1228 __func__, ret);
1229 break;
1230 case FORMAT_APTX:
1231 pr_debug("SND_AUDIOCODEC_APTX\n");
1232 memset(&aptx_cfg, 0x0, sizeof(struct aptx_dec_bt_addr_cfg));
1233 ret = q6asm_stream_media_format_block_aptx_dec(
1234 prtd->audio_client,
1235 prtd->sample_rate,
1236 stream_id);
1237 if (ret >= 0) {
1238 aptx_cfg.nap = codec_options->aptx_dec.nap;
1239 aptx_cfg.uap = codec_options->aptx_dec.uap;
1240 aptx_cfg.lap = codec_options->aptx_dec.lap;
1241 q6asm_set_aptx_dec_bt_addr(prtd->audio_client,
1242 &aptx_cfg);
1243 } else {
1244 pr_err("%s: CMD Format block failed ret %d\n",
1245 __func__, ret);
1246 }
1247 break;
1248 default:
1249 pr_debug("%s, unsupported format, skip", __func__);
1250 break;
1251 }
1252 return ret;
1253}
1254
1255static int msm_compr_init_pp_params(struct snd_compr_stream *cstream,
1256 struct audio_client *ac)
1257{
1258 int ret = 0;
1259 struct asm_softvolume_params softvol = {
1260 .period = SOFT_VOLUME_PERIOD,
1261 .step = SOFT_VOLUME_STEP,
1262 .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
1263 };
1264
1265 switch (ac->topology) {
1266 default:
1267 ret = q6asm_set_softvolume_v2(ac, &softvol,
1268 SOFT_VOLUME_INSTANCE_1);
1269 if (ret < 0)
1270 pr_err("%s: Send SoftVolume Param failed ret=%d\n",
1271 __func__, ret);
1272
1273 break;
1274 }
1275 return ret;
1276}
1277
1278static int msm_compr_configure_dsp_for_playback
1279 (struct snd_compr_stream *cstream)
1280{
1281 struct snd_compr_runtime *runtime = cstream->runtime;
1282 struct msm_compr_audio *prtd = runtime->private_data;
1283 struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data;
1284 uint16_t bits_per_sample = 16;
1285 int dir = IN, ret = 0;
1286 struct audio_client *ac = prtd->audio_client;
1287 uint32_t stream_index;
1288 struct asm_softpause_params softpause = {
1289 .enable = SOFT_PAUSE_ENABLE,
1290 .period = SOFT_PAUSE_PERIOD,
1291 .step = SOFT_PAUSE_STEP,
1292 .rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
1293 };
1294 struct asm_softvolume_params softvol = {
1295 .period = SOFT_VOLUME_PERIOD,
1296 .step = SOFT_VOLUME_STEP,
1297 .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
1298 };
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301299 struct snd_kcontrol *kctl;
1300 struct snd_ctl_elem_value kctl_elem_value;
1301 uint16_t target_asm_bit_width = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301302
1303 pr_debug("%s: stream_id %d\n", __func__, ac->stream_id);
1304 stream_index = STREAM_ARRAY_INDEX(ac->stream_id);
1305 if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) {
1306 pr_err("%s: Invalid stream index:%d", __func__, stream_index);
1307 return -EINVAL;
1308 }
1309
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301310 kctl = snd_soc_card_get_kcontrol(soc_prtd->card,
1311 DSP_BIT_WIDTH_MIXER_CTL);
1312 if (kctl) {
1313 kctl->get(kctl, &kctl_elem_value);
1314 target_asm_bit_width = kctl_elem_value.value.integer.value[0];
1315 if (target_asm_bit_width > 0) {
1316 pr_debug("%s enforce ASM bitwidth to %d from %d\n",
1317 __func__,
1318 target_asm_bit_width,
1319 bits_per_sample);
1320 bits_per_sample = target_asm_bit_width;
1321 }
1322 } else {
1323 pr_info("%s: failed to get mixer ctl for %s.\n",
1324 __func__, DSP_BIT_WIDTH_MIXER_CTL);
1325 }
1326
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301327 if ((prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) ||
1328 (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_3LE))
1329 bits_per_sample = 24;
1330 else if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S32_LE)
1331 bits_per_sample = 32;
1332
1333 if (prtd->compr_passthr != LEGACY_PCM) {
1334 ret = q6asm_open_write_compressed(ac, prtd->codec,
1335 prtd->compr_passthr);
1336 if (ret < 0) {
1337 pr_err("%s:ASM open write err[%d] for compr_type[%d]\n",
1338 __func__, ret, prtd->compr_passthr);
1339 return ret;
1340 }
1341 prtd->gapless_state.stream_opened[stream_index] = 1;
1342
1343 ret = msm_pcm_routing_reg_phy_compr_stream(
1344 soc_prtd->dai_link->id,
1345 ac->perf_mode,
1346 prtd->session_id,
1347 SNDRV_PCM_STREAM_PLAYBACK,
1348 prtd->compr_passthr);
1349 if (ret) {
1350 pr_err("%s: compr stream reg failed:%d\n", __func__,
1351 ret);
1352 return ret;
1353 }
1354 } else {
1355 pr_debug("%s: stream_id %d bits_per_sample %d\n",
1356 __func__, ac->stream_id, bits_per_sample);
Dieter Lueckingba7644d2018-09-28 15:09:32 +02001357
1358 if (q6core_get_avcs_api_version_per_service(
1359 APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
1360 ADSP_ASM_API_VERSION_V2)
1361 ret = q6asm_stream_open_write_v5(ac,
1362 prtd->codec, bits_per_sample,
1363 ac->stream_id,
1364 prtd->gapless_state.use_dsp_gapless_mode);
1365 else
1366 ret = q6asm_stream_open_write_v4(ac,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301367 prtd->codec, bits_per_sample,
1368 ac->stream_id,
1369 prtd->gapless_state.use_dsp_gapless_mode);
1370 if (ret < 0) {
1371 pr_err("%s:ASM open write err[%d] for compr type[%d]\n",
1372 __func__, ret, prtd->compr_passthr);
1373 return -ENOMEM;
1374 }
1375 prtd->gapless_state.stream_opened[stream_index] = 1;
1376
1377 pr_debug("%s: BE id %d\n", __func__, soc_prtd->dai_link->id);
1378 ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id,
1379 ac->perf_mode,
1380 prtd->session_id,
1381 SNDRV_PCM_STREAM_PLAYBACK);
1382 if (ret) {
1383 pr_err("%s: stream reg failed:%d\n", __func__, ret);
1384 return ret;
1385 }
1386 }
1387
1388 ret = msm_compr_set_volume(cstream, 0, 0);
1389 if (ret < 0)
1390 pr_err("%s : Set Volume failed : %d", __func__, ret);
1391
1392 if (prtd->compr_passthr != LEGACY_PCM) {
1393 pr_debug("%s : Don't send cal and PP params for compress path",
1394 __func__);
1395 } else {
1396 ret = q6asm_send_cal(ac);
1397 if (ret < 0)
1398 pr_debug("%s : Send cal failed : %d", __func__, ret);
1399
1400 ret = q6asm_set_softpause(ac, &softpause);
1401 if (ret < 0)
1402 pr_err("%s: Send SoftPause Param failed ret=%d\n",
1403 __func__, ret);
1404
1405 ret = q6asm_set_softvolume(ac, &softvol);
1406 if (ret < 0)
1407 pr_err("%s: Send SoftVolume Param failed ret=%d\n",
1408 __func__, ret);
1409 }
1410 ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
1411 if (ret < 0) {
1412 pr_err("%s: Set IO mode failed\n", __func__);
1413 return -EINVAL;
1414 }
1415
1416 runtime->fragments = prtd->codec_param.buffer.fragments;
1417 runtime->fragment_size = prtd->codec_param.buffer.fragment_size;
1418 pr_debug("allocate %d buffers each of size %d\n",
1419 runtime->fragments,
1420 runtime->fragment_size);
1421 ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac,
1422 runtime->fragment_size,
1423 runtime->fragments);
1424 if (ret < 0) {
1425 pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret);
1426 return -ENOMEM;
1427 }
1428
1429 prtd->byte_offset = 0;
1430 prtd->copied_total = 0;
1431 prtd->app_pointer = 0;
1432 prtd->bytes_received = 0;
1433 prtd->bytes_sent = 0;
1434 prtd->buffer = ac->port[dir].buf[0].data;
1435 prtd->buffer_paddr = ac->port[dir].buf[0].phys;
1436 prtd->buffer_size = runtime->fragments * runtime->fragment_size;
1437
1438 /* Bit-0 of flags represent timestamp mode */
1439 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG)
1440 prtd->ts_header_offset = sizeof(struct snd_codec_metadata);
1441 else
1442 prtd->ts_header_offset = 0;
1443
1444 ret = msm_compr_send_media_format_block(cstream, ac->stream_id, false);
1445 if (ret < 0)
1446 pr_err("%s, failed to send media format block\n", __func__);
1447
1448 return ret;
1449}
1450
1451static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
1452{
1453 struct snd_compr_runtime *runtime = cstream->runtime;
1454 struct msm_compr_audio *prtd = runtime->private_data;
1455 struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data;
1456 uint16_t bits_per_sample;
1457 uint16_t sample_word_size;
1458 int dir = OUT, ret = 0;
1459 struct audio_client *ac = prtd->audio_client;
1460 uint32_t stream_index;
1461
1462 switch (prtd->codec_param.codec.format) {
1463 case SNDRV_PCM_FORMAT_S24_LE:
1464 bits_per_sample = 24;
1465 sample_word_size = 32;
1466 break;
1467 case SNDRV_PCM_FORMAT_S24_3LE:
1468 bits_per_sample = 24;
1469 sample_word_size = 24;
1470 break;
1471 case SNDRV_PCM_FORMAT_S32_LE:
1472 bits_per_sample = 32;
1473 sample_word_size = 32;
1474 break;
1475 case SNDRV_PCM_FORMAT_S16_LE:
1476 default:
1477 bits_per_sample = 16;
1478 sample_word_size = 16;
1479 break;
1480 }
1481
1482 pr_debug("%s: stream_id %d bits_per_sample %d\n",
1483 __func__, ac->stream_id, bits_per_sample);
1484
1485 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
1486 ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
1487 bits_per_sample, true);
1488 } else {
1489 ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
1490 bits_per_sample, false);
1491 }
1492 if (ret < 0) {
1493 pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret);
1494 return ret;
1495 }
1496
1497 ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id,
1498 ac->perf_mode,
1499 prtd->session_id,
1500 SNDRV_PCM_STREAM_CAPTURE);
1501 if (ret) {
1502 pr_err("%s: stream reg failed:%d\n", __func__, ret);
1503 return ret;
1504 }
1505
1506 ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
1507 if (ret < 0) {
1508 pr_err("%s: Set IO mode failed\n", __func__);
1509 return -EINVAL;
1510 }
1511
1512 stream_index = STREAM_ARRAY_INDEX(ac->stream_id);
1513 if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) {
1514 pr_err("%s: Invalid stream index:%d", __func__, stream_index);
1515 return -EINVAL;
1516 }
1517
1518 runtime->fragments = prtd->codec_param.buffer.fragments;
1519 runtime->fragment_size = prtd->codec_param.buffer.fragment_size;
1520 pr_debug("%s: allocate %d buffers each of size %d\n",
1521 __func__, runtime->fragments,
1522 runtime->fragment_size);
1523 ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac,
1524 runtime->fragment_size,
1525 runtime->fragments);
1526 if (ret < 0) {
1527 pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret);
1528 return -ENOMEM;
1529 }
1530
1531 prtd->byte_offset = 0;
1532 prtd->received_total = 0;
1533 prtd->app_pointer = 0;
1534 prtd->bytes_copied = 0;
1535 prtd->bytes_read = 0;
1536 prtd->bytes_read_offset = 0;
1537 prtd->buffer = ac->port[dir].buf[0].data;
1538 prtd->buffer_paddr = ac->port[dir].buf[0].phys;
1539 prtd->buffer_size = runtime->fragments * runtime->fragment_size;
1540
1541 /* Bit-0 of flags represent timestamp mode */
1542 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG)
1543 prtd->ts_header_offset = sizeof(struct snd_codec_metadata);
1544 else
1545 prtd->ts_header_offset = 0;
1546
1547 pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
1548 __func__, prtd->sample_rate, prtd->num_channels,
1549 bits_per_sample, sample_word_size);
Sachin Mohan Gadag265d94d2018-01-04 11:04:00 +05301550 ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301551 prtd->sample_rate, prtd->num_channels,
Sachin Mohan Gadag265d94d2018-01-04 11:04:00 +05301552 bits_per_sample, sample_word_size,
1553 ASM_LITTLE_ENDIAN, DEFAULT_QF);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301554
1555 return ret;
1556}
1557
1558static int msm_compr_playback_open(struct snd_compr_stream *cstream)
1559{
1560 struct snd_compr_runtime *runtime = cstream->runtime;
1561 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
Aditya Bavanari9deef912017-11-20 13:31:31 +05301562 struct msm_compr_audio *prtd = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301563 struct msm_compr_pdata *pdata =
1564 snd_soc_platform_get_drvdata(rtd->platform);
1565
1566 pr_debug("%s\n", __func__);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301567 if (pdata->is_in_use[rtd->dai_link->id] == true) {
1568 pr_err("%s: %s is already in use, err: %d\n",
1569 __func__, rtd->dai_link->cpu_dai_name, -EBUSY);
1570 return -EBUSY;
1571 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301572 prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
1573 if (prtd == NULL) {
1574 pr_err("Failed to allocate memory for msm_compr_audio\n");
1575 return -ENOMEM;
1576 }
1577
1578 runtime->private_data = NULL;
1579 prtd->cstream = cstream;
1580 pdata->cstream[rtd->dai_link->id] = cstream;
1581 pdata->audio_effects[rtd->dai_link->id] =
1582 kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301583 if (pdata->audio_effects[rtd->dai_link->id] == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301584 pr_err("%s: Could not allocate memory for effects\n", __func__);
1585 pdata->cstream[rtd->dai_link->id] = NULL;
1586 kfree(prtd);
1587 return -ENOMEM;
1588 }
1589 pdata->dec_params[rtd->dai_link->id] =
1590 kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301591 if (pdata->dec_params[rtd->dai_link->id] == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301592 pr_err("%s: Could not allocate memory for dec params\n",
1593 __func__);
1594 kfree(pdata->audio_effects[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301595 pdata->audio_effects[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301596 pdata->cstream[rtd->dai_link->id] = NULL;
1597 kfree(prtd);
1598 return -ENOMEM;
1599 }
1600 prtd->codec = FORMAT_MP3;
1601 prtd->bytes_received = 0;
1602 prtd->bytes_sent = 0;
1603 prtd->copied_total = 0;
1604 prtd->byte_offset = 0;
1605 prtd->sample_rate = 44100;
1606 prtd->num_channels = 2;
1607 prtd->drain_ready = 0;
1608 prtd->last_buffer = 0;
1609 prtd->first_buffer = 1;
1610 prtd->partial_drain_delay = 0;
1611 prtd->next_stream = 0;
1612 memset(&prtd->gapless_state, 0, sizeof(struct msm_compr_gapless_state));
1613 /*
1614 * Update the use_dsp_gapless_mode from gapless struture with the value
1615 * part of platform data.
1616 */
1617 prtd->gapless_state.use_dsp_gapless_mode = pdata->use_dsp_gapless_mode;
1618
1619 pr_debug("%s: gapless mode %d", __func__, pdata->use_dsp_gapless_mode);
1620
1621 spin_lock_init(&prtd->lock);
1622
1623 atomic_set(&prtd->eos, 0);
1624 atomic_set(&prtd->start, 0);
1625 atomic_set(&prtd->drain, 0);
1626 atomic_set(&prtd->xrun, 0);
1627 atomic_set(&prtd->close, 0);
1628 atomic_set(&prtd->wait_on_close, 0);
1629 atomic_set(&prtd->error, 0);
1630
1631 init_waitqueue_head(&prtd->eos_wait);
1632 init_waitqueue_head(&prtd->drain_wait);
1633 init_waitqueue_head(&prtd->close_wait);
1634 init_waitqueue_head(&prtd->wait_for_stream_avail);
1635
1636 runtime->private_data = prtd;
1637 populate_codec_list(prtd);
1638 prtd->audio_client = q6asm_audio_client_alloc(
1639 (app_cb)compr_event_handler, prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301640 if (prtd->audio_client == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301641 pr_err("%s: Could not allocate memory for client\n", __func__);
1642 kfree(pdata->audio_effects[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301643 pdata->audio_effects[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301644 kfree(pdata->dec_params[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301645 pdata->dec_params[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301646 pdata->cstream[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301647 kfree(prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301648 runtime->private_data = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301649 return -ENOMEM;
1650 }
1651 pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session);
1652 prtd->audio_client->perf_mode = false;
1653 prtd->session_id = prtd->audio_client->session;
1654 msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301655 pdata->is_in_use[rtd->dai_link->id] = true;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301656 return 0;
1657}
1658
1659static int msm_compr_capture_open(struct snd_compr_stream *cstream)
1660{
1661 struct snd_compr_runtime *runtime = cstream->runtime;
1662 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
1663 struct msm_compr_audio *prtd;
1664 struct msm_compr_pdata *pdata =
1665 snd_soc_platform_get_drvdata(rtd->platform);
1666
1667 pr_debug("%s\n", __func__);
1668 prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
1669 if (prtd == NULL) {
1670 pr_err("Failed to allocate memory for msm_compr_audio\n");
1671 return -ENOMEM;
1672 }
1673
1674 runtime->private_data = NULL;
1675 prtd->cstream = cstream;
1676 pdata->cstream[rtd->dai_link->id] = cstream;
1677
1678 prtd->audio_client = q6asm_audio_client_alloc(
1679 (app_cb)compr_event_handler, prtd);
1680 if (!prtd->audio_client) {
1681 pr_err("%s: Could not allocate memory for client\n", __func__);
1682 pdata->cstream[rtd->dai_link->id] = NULL;
1683 kfree(prtd);
1684 return -ENOMEM;
1685 }
1686 pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session);
1687 prtd->audio_client->perf_mode = false;
1688 prtd->session_id = prtd->audio_client->session;
1689 prtd->codec = FORMAT_LINEAR_PCM;
1690 prtd->bytes_copied = 0;
1691 prtd->bytes_read = 0;
1692 prtd->bytes_read_offset = 0;
1693 prtd->received_total = 0;
1694 prtd->byte_offset = 0;
1695 prtd->sample_rate = 48000;
1696 prtd->num_channels = 2;
1697 prtd->first_buffer = 0;
1698
1699 spin_lock_init(&prtd->lock);
1700
1701 atomic_set(&prtd->eos, 0);
1702 atomic_set(&prtd->start, 0);
1703 atomic_set(&prtd->drain, 0);
1704 atomic_set(&prtd->xrun, 0);
1705 atomic_set(&prtd->close, 0);
1706 atomic_set(&prtd->wait_on_close, 0);
1707 atomic_set(&prtd->error, 0);
1708
1709 runtime->private_data = prtd;
1710
1711 return 0;
1712}
1713
1714static int msm_compr_open(struct snd_compr_stream *cstream)
1715{
1716 int ret = 0;
1717
1718 if (cstream->direction == SND_COMPRESS_PLAYBACK)
1719 ret = msm_compr_playback_open(cstream);
1720 else if (cstream->direction == SND_COMPRESS_CAPTURE)
1721 ret = msm_compr_capture_open(cstream);
1722 return ret;
1723}
1724
1725static int msm_compr_playback_free(struct snd_compr_stream *cstream)
1726{
1727 struct snd_compr_runtime *runtime;
1728 struct msm_compr_audio *prtd;
1729 struct snd_soc_pcm_runtime *soc_prtd;
1730 struct msm_compr_pdata *pdata;
1731 struct audio_client *ac;
1732 int dir = IN, ret = 0, stream_id;
1733 unsigned long flags;
1734 uint32_t stream_index;
1735
1736 pr_debug("%s\n", __func__);
1737
1738 if (!cstream) {
1739 pr_err("%s cstream is null\n", __func__);
1740 return 0;
1741 }
1742 runtime = cstream->runtime;
1743 soc_prtd = cstream->private_data;
1744 if (!runtime || !soc_prtd || !(soc_prtd->platform)) {
1745 pr_err("%s runtime or soc_prtd or platform is null\n",
1746 __func__);
1747 return 0;
1748 }
1749 prtd = runtime->private_data;
1750 if (!prtd) {
1751 pr_err("%s prtd is null\n", __func__);
1752 return 0;
1753 }
1754 prtd->cmd_interrupt = 1;
1755 wake_up(&prtd->drain_wait);
1756 pdata = snd_soc_platform_get_drvdata(soc_prtd->platform);
1757 ac = prtd->audio_client;
1758 if (!pdata || !ac) {
1759 pr_err("%s pdata or ac is null\n", __func__);
1760 return 0;
1761 }
1762 if (atomic_read(&prtd->eos)) {
1763 ret = wait_event_timeout(prtd->eos_wait,
1764 prtd->eos_ack, 5 * HZ);
1765 if (!ret)
1766 pr_err("%s: CMD_EOS failed\n", __func__);
1767 }
1768 if (atomic_read(&prtd->close)) {
1769 prtd->cmd_ack = 0;
1770 atomic_set(&prtd->wait_on_close, 1);
1771 ret = wait_event_timeout(prtd->close_wait,
1772 prtd->cmd_ack, 5 * HZ);
1773 if (!ret)
1774 pr_err("%s: CMD_CLOSE failed\n", __func__);
1775 }
1776
1777 spin_lock_irqsave(&prtd->lock, flags);
1778 stream_id = ac->stream_id;
1779 stream_index = STREAM_ARRAY_INDEX(NEXT_STREAM_ID(stream_id));
1780
1781 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
1782 (prtd->gapless_state.stream_opened[stream_index])) {
1783 prtd->gapless_state.stream_opened[stream_index] = 0;
1784 spin_unlock_irqrestore(&prtd->lock, flags);
1785 pr_debug(" close stream %d", NEXT_STREAM_ID(stream_id));
1786 q6asm_stream_cmd(ac, CMD_CLOSE, NEXT_STREAM_ID(stream_id));
1787 spin_lock_irqsave(&prtd->lock, flags);
1788 }
1789
1790 stream_index = STREAM_ARRAY_INDEX(stream_id);
1791 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
1792 (prtd->gapless_state.stream_opened[stream_index])) {
1793 prtd->gapless_state.stream_opened[stream_index] = 0;
1794 spin_unlock_irqrestore(&prtd->lock, flags);
1795 pr_debug("close stream %d", stream_id);
1796 q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
1797 spin_lock_irqsave(&prtd->lock, flags);
1798 }
1799 spin_unlock_irqrestore(&prtd->lock, flags);
1800
1801 pdata->cstream[soc_prtd->dai_link->id] = NULL;
1802 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
1803 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
1804 SNDRV_PCM_STREAM_PLAYBACK);
1805 }
1806
1807 q6asm_audio_client_buf_free_contiguous(dir, ac);
1808
1809 q6asm_audio_client_free(ac);
1810 msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301811 if (pdata->audio_effects[soc_prtd->dai_link->id] != NULL) {
1812 kfree(pdata->audio_effects[soc_prtd->dai_link->id]);
1813 pdata->audio_effects[soc_prtd->dai_link->id] = NULL;
1814 }
1815 if (pdata->dec_params[soc_prtd->dai_link->id] != NULL) {
1816 kfree(pdata->dec_params[soc_prtd->dai_link->id]);
1817 pdata->dec_params[soc_prtd->dai_link->id] = NULL;
1818 }
1819 pdata->is_in_use[soc_prtd->dai_link->id] = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301820 kfree(prtd);
1821 runtime->private_data = NULL;
1822
1823 return 0;
1824}
1825
1826static int msm_compr_capture_free(struct snd_compr_stream *cstream)
1827{
1828 struct snd_compr_runtime *runtime;
1829 struct msm_compr_audio *prtd;
1830 struct snd_soc_pcm_runtime *soc_prtd;
1831 struct msm_compr_pdata *pdata;
1832 struct audio_client *ac;
1833 int dir = OUT, stream_id;
1834 unsigned long flags;
1835 uint32_t stream_index;
1836
1837 if (!cstream) {
1838 pr_err("%s cstream is null\n", __func__);
1839 return 0;
1840 }
1841 runtime = cstream->runtime;
1842 soc_prtd = cstream->private_data;
1843 if (!runtime || !soc_prtd || !(soc_prtd->platform)) {
1844 pr_err("%s runtime or soc_prtd or platform is null\n",
1845 __func__);
1846 return 0;
1847 }
1848 prtd = runtime->private_data;
1849 if (!prtd) {
1850 pr_err("%s prtd is null\n", __func__);
1851 return 0;
1852 }
1853 pdata = snd_soc_platform_get_drvdata(soc_prtd->platform);
1854 ac = prtd->audio_client;
1855 if (!pdata || !ac) {
1856 pr_err("%s pdata or ac is null\n", __func__);
1857 return 0;
1858 }
1859
1860 spin_lock_irqsave(&prtd->lock, flags);
1861 stream_id = ac->stream_id;
1862
1863 stream_index = STREAM_ARRAY_INDEX(stream_id);
1864 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0)) {
1865 spin_unlock_irqrestore(&prtd->lock, flags);
1866 pr_debug("close stream %d", stream_id);
1867 q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
1868 spin_lock_irqsave(&prtd->lock, flags);
1869 }
1870 spin_unlock_irqrestore(&prtd->lock, flags);
1871
1872 pdata->cstream[soc_prtd->dai_link->id] = NULL;
1873 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
1874 SNDRV_PCM_STREAM_CAPTURE);
1875
1876 q6asm_audio_client_buf_free_contiguous(dir, ac);
1877
1878 q6asm_audio_client_free(ac);
1879
1880 kfree(prtd);
1881 runtime->private_data = NULL;
1882
1883 return 0;
1884}
1885
1886static int msm_compr_free(struct snd_compr_stream *cstream)
1887{
1888 int ret = 0;
1889
1890 if (cstream->direction == SND_COMPRESS_PLAYBACK)
1891 ret = msm_compr_playback_free(cstream);
1892 else if (cstream->direction == SND_COMPRESS_CAPTURE)
1893 ret = msm_compr_capture_free(cstream);
1894 return ret;
1895}
1896
1897static bool msm_compr_validate_codec_compr(__u32 codec_id)
1898{
1899 int32_t i;
1900
1901 for (i = 0; i < ARRAY_SIZE(compr_codecs); i++) {
1902 if (compr_codecs[i] == codec_id)
1903 return true;
1904 }
1905 return false;
1906}
1907
1908/* compress stream operations */
1909static int msm_compr_set_params(struct snd_compr_stream *cstream,
1910 struct snd_compr_params *params)
1911{
1912 struct snd_compr_runtime *runtime = cstream->runtime;
1913 struct msm_compr_audio *prtd = runtime->private_data;
1914 int ret = 0, frame_sz = 0;
1915 int i, num_rates;
1916 bool is_format_gapless = false;
1917
1918 pr_debug("%s\n", __func__);
1919
1920 num_rates = sizeof(supported_sample_rates)/sizeof(unsigned int);
1921 for (i = 0; i < num_rates; i++)
1922 if (params->codec.sample_rate == supported_sample_rates[i])
1923 break;
1924 if (i == num_rates)
1925 return -EINVAL;
1926
1927 memcpy(&prtd->codec_param, params, sizeof(struct snd_compr_params));
1928 /* ToDo: remove duplicates */
1929 prtd->num_channels = prtd->codec_param.codec.ch_in;
1930 prtd->sample_rate = prtd->codec_param.codec.sample_rate;
1931 pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
1932
1933 if ((prtd->codec_param.codec.compr_passthr >= LEGACY_PCM &&
1934 prtd->codec_param.
1935 codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD) ||
1936 (prtd->codec_param.
1937 codec.compr_passthr == COMPRESSED_PASSTHROUGH_IEC61937))
1938 prtd->compr_passthr = prtd->codec_param.codec.compr_passthr;
1939 else
1940 prtd->compr_passthr = LEGACY_PCM;
1941 pr_debug("%s: compr_passthr = %d", __func__, prtd->compr_passthr);
1942 if (prtd->compr_passthr != LEGACY_PCM) {
1943 pr_debug("%s: Reset gapless mode playback for compr_type[%d]\n",
1944 __func__, prtd->compr_passthr);
1945 prtd->gapless_state.use_dsp_gapless_mode = 0;
1946 if (!msm_compr_validate_codec_compr(params->codec.id)) {
1947 pr_err("%s codec not supported in passthrough,id =%d\n",
1948 __func__, params->codec.id);
1949 return -EINVAL;
1950 }
1951 }
1952
1953 switch (params->codec.id) {
1954 case SND_AUDIOCODEC_PCM: {
1955 pr_debug("SND_AUDIOCODEC_PCM\n");
1956 prtd->codec = FORMAT_LINEAR_PCM;
1957 is_format_gapless = true;
1958 break;
1959 }
1960
1961 case SND_AUDIOCODEC_MP3: {
1962 pr_debug("SND_AUDIOCODEC_MP3\n");
1963 prtd->codec = FORMAT_MP3;
1964 frame_sz = MP3_OUTPUT_FRAME_SZ;
1965 is_format_gapless = true;
1966 break;
1967 }
1968
1969 case SND_AUDIOCODEC_AAC: {
1970 pr_debug("SND_AUDIOCODEC_AAC\n");
1971 prtd->codec = FORMAT_MPEG4_AAC;
1972 frame_sz = AAC_OUTPUT_FRAME_SZ;
1973 is_format_gapless = true;
1974 break;
1975 }
1976
1977 case SND_AUDIOCODEC_AC3: {
1978 pr_debug("SND_AUDIOCODEC_AC3\n");
1979 prtd->codec = FORMAT_AC3;
1980 frame_sz = AC3_OUTPUT_FRAME_SZ;
1981 is_format_gapless = true;
1982 break;
1983 }
1984
1985 case SND_AUDIOCODEC_EAC3: {
1986 pr_debug("SND_AUDIOCODEC_EAC3\n");
1987 prtd->codec = FORMAT_EAC3;
1988 frame_sz = EAC3_OUTPUT_FRAME_SZ;
1989 is_format_gapless = true;
1990 break;
1991 }
1992
1993 case SND_AUDIOCODEC_MP2: {
1994 pr_debug("SND_AUDIOCODEC_MP2\n");
1995 prtd->codec = FORMAT_MP2;
1996 break;
1997 }
1998
1999 case SND_AUDIOCODEC_WMA: {
2000 pr_debug("SND_AUDIOCODEC_WMA\n");
2001 prtd->codec = FORMAT_WMA_V9;
2002 break;
2003 }
2004
2005 case SND_AUDIOCODEC_WMA_PRO: {
2006 pr_debug("SND_AUDIOCODEC_WMA_PRO\n");
2007 prtd->codec = FORMAT_WMA_V10PRO;
2008 break;
2009 }
2010
2011 case SND_AUDIOCODEC_FLAC: {
2012 pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
2013 prtd->codec = FORMAT_FLAC;
2014 /*
2015 * DSP bufferring is based on blk size,
2016 * consider mininum buffering to rule out any false wait
2017 */
2018 frame_sz =
2019 prtd->codec_param.codec.options.flac_dec.min_blk_size;
2020 is_format_gapless = true;
2021 break;
2022 }
2023
2024 case SND_AUDIOCODEC_VORBIS: {
2025 pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__);
2026 prtd->codec = FORMAT_VORBIS;
2027 break;
2028 }
2029
2030 case SND_AUDIOCODEC_ALAC: {
2031 pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__);
2032 prtd->codec = FORMAT_ALAC;
2033 break;
2034 }
2035
2036 case SND_AUDIOCODEC_APE: {
2037 pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__);
2038 prtd->codec = FORMAT_APE;
2039 break;
2040 }
2041
2042 case SND_AUDIOCODEC_DTS: {
2043 pr_debug("%s: SND_AUDIOCODEC_DTS\n", __func__);
2044 prtd->codec = FORMAT_DTS;
2045 break;
2046 }
2047
2048 case SND_AUDIOCODEC_DSD: {
2049 pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
2050 prtd->codec = FORMAT_DSD;
2051 break;
2052 }
2053
2054 case SND_AUDIOCODEC_TRUEHD: {
2055 pr_debug("%s: SND_AUDIOCODEC_TRUEHD\n", __func__);
2056 prtd->codec = FORMAT_TRUEHD;
2057 break;
2058 }
2059
2060 case SND_AUDIOCODEC_IEC61937: {
2061 pr_debug("%s: SND_AUDIOCODEC_IEC61937\n", __func__);
2062 prtd->codec = FORMAT_IEC61937;
2063 break;
2064 }
2065
2066 case SND_AUDIOCODEC_APTX: {
2067 pr_debug("%s: SND_AUDIOCODEC_APTX\n", __func__);
2068 prtd->codec = FORMAT_APTX;
2069 break;
2070 }
2071
2072 default:
2073 pr_err("codec not supported, id =%d\n", params->codec.id);
2074 return -EINVAL;
2075 }
2076
2077 if (!is_format_gapless)
2078 prtd->gapless_state.use_dsp_gapless_mode = false;
2079
2080 prtd->partial_drain_delay =
2081 msm_compr_get_partial_drain_delay(frame_sz, prtd->sample_rate);
2082
2083 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2084 ret = msm_compr_configure_dsp_for_playback(cstream);
2085 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2086 ret = msm_compr_configure_dsp_for_capture(cstream);
2087
2088 return ret;
2089}
2090
2091static int msm_compr_drain_buffer(struct msm_compr_audio *prtd,
2092 unsigned long *flags)
2093{
2094 int rc = 0;
2095
2096 atomic_set(&prtd->drain, 1);
2097 prtd->drain_ready = 0;
2098 spin_unlock_irqrestore(&prtd->lock, *flags);
2099 pr_debug("%s: wait for buffer to be drained\n", __func__);
2100 rc = wait_event_interruptible(prtd->drain_wait,
2101 prtd->drain_ready ||
2102 prtd->cmd_interrupt ||
2103 atomic_read(&prtd->xrun) ||
2104 atomic_read(&prtd->error));
2105 pr_debug("%s: out of buffer drain wait with ret %d\n", __func__, rc);
2106 spin_lock_irqsave(&prtd->lock, *flags);
2107 if (prtd->cmd_interrupt) {
2108 pr_debug("%s: buffer drain interrupted by flush)\n", __func__);
2109 rc = -EINTR;
2110 prtd->cmd_interrupt = 0;
2111 }
2112 if (atomic_read(&prtd->error)) {
2113 pr_err("%s: Got RESET EVENTS notification, return\n",
2114 __func__);
2115 rc = -ENETRESET;
2116 }
2117 return rc;
2118}
2119
2120static int msm_compr_wait_for_stream_avail(struct msm_compr_audio *prtd,
2121 unsigned long *flags)
2122{
2123 int rc = 0;
2124
2125 pr_debug("next session is already in opened state\n");
2126 prtd->next_stream = 1;
2127 prtd->cmd_interrupt = 0;
2128 spin_unlock_irqrestore(&prtd->lock, *flags);
2129 /*
2130 * Wait for stream to be available, or the wait to be interrupted by
2131 * commands like flush or till a timeout of one second.
2132 */
2133 rc = wait_event_timeout(prtd->wait_for_stream_avail,
2134 prtd->stream_available || prtd->cmd_interrupt, 1 * HZ);
2135 pr_err("%s:prtd->stream_available %d, prtd->cmd_interrupt %d rc %d\n",
2136 __func__, prtd->stream_available, prtd->cmd_interrupt, rc);
2137
2138 spin_lock_irqsave(&prtd->lock, *flags);
2139 if (rc == 0) {
2140 pr_err("%s: wait_for_stream_avail timed out\n",
2141 __func__);
2142 rc = -ETIMEDOUT;
2143 } else if (prtd->cmd_interrupt == 1) {
2144 /*
2145 * This scenario might not happen as we do not allow
2146 * flush in transition state.
2147 */
2148 pr_debug("%s: wait_for_stream_avail interrupted\n", __func__);
2149 prtd->cmd_interrupt = 0;
2150 prtd->stream_available = 0;
2151 rc = -EINTR;
2152 } else {
2153 prtd->stream_available = 0;
2154 rc = 0;
2155 }
2156 pr_debug("%s : rc = %d", __func__, rc);
2157 return rc;
2158}
2159
2160static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
2161{
2162 struct snd_compr_runtime *runtime = cstream->runtime;
2163 struct msm_compr_audio *prtd = runtime->private_data;
2164 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
2165 struct msm_compr_pdata *pdata =
2166 snd_soc_platform_get_drvdata(rtd->platform);
2167 uint32_t *volume = pdata->volume[rtd->dai_link->id];
2168 struct audio_client *ac = prtd->audio_client;
2169 unsigned long fe_id = rtd->dai_link->id;
2170 int rc = 0;
2171 int bytes_to_write;
2172 unsigned long flags;
2173 int stream_id;
2174 uint32_t stream_index;
2175 uint16_t bits_per_sample = 16;
2176
2177 spin_lock_irqsave(&prtd->lock, flags);
2178 if (atomic_read(&prtd->error)) {
2179 pr_err("%s Got RESET EVENTS notification, return immediately",
2180 __func__);
2181 spin_unlock_irqrestore(&prtd->lock, flags);
2182 return 0;
2183 }
2184 spin_unlock_irqrestore(&prtd->lock, flags);
2185
2186 switch (cmd) {
2187 case SNDRV_PCM_TRIGGER_START:
2188 pr_debug("%s: SNDRV_PCM_TRIGGER_START\n", __func__);
2189 atomic_set(&prtd->start, 1);
2190
2191 /*
2192 * compr_set_volume and compr_init_pp_params
2193 * are used to configure ASM volume hence not
2194 * needed for compress passthrough playback.
2195 *
2196 * compress passthrough volume is controlled in
2197 * ADM by adm_send_compressed_device_mute()
2198 */
2199 if (prtd->compr_passthr == LEGACY_PCM &&
2200 cstream->direction == SND_COMPRESS_PLAYBACK) {
2201 /* set volume for the stream before RUN */
2202 rc = msm_compr_set_volume(cstream,
2203 volume[0], volume[1]);
2204 if (rc)
2205 pr_err("%s : Set Volume failed : %d\n",
2206 __func__, rc);
2207
2208 rc = msm_compr_init_pp_params(cstream, ac);
2209 if (rc)
2210 pr_err("%s : init PP params failed : %d\n",
2211 __func__, rc);
2212 } else {
2213 msm_compr_read_buffer(prtd);
2214 }
2215 /* issue RUN command for the stream */
2216 q6asm_run_nowait(prtd->audio_client, prtd->run_mode,
2217 prtd->start_delay_msw, prtd->start_delay_lsw);
2218 break;
2219 case SNDRV_PCM_TRIGGER_STOP:
2220 spin_lock_irqsave(&prtd->lock, flags);
2221 pr_debug("%s: SNDRV_PCM_TRIGGER_STOP transition %d\n", __func__,
2222 prtd->gapless_state.gapless_transition);
2223 stream_id = ac->stream_id;
2224 atomic_set(&prtd->start, 0);
2225 if (cstream->direction == SND_COMPRESS_CAPTURE) {
2226 q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
2227 atomic_set(&prtd->xrun, 0);
2228 prtd->received_total = 0;
2229 prtd->bytes_copied = 0;
2230 prtd->bytes_read = 0;
2231 prtd->bytes_read_offset = 0;
2232 prtd->byte_offset = 0;
2233 prtd->app_pointer = 0;
2234 spin_unlock_irqrestore(&prtd->lock, flags);
2235 break;
2236 }
2237 if (prtd->next_stream) {
2238 pr_debug("%s: interrupt next track wait queues\n",
2239 __func__);
2240 prtd->cmd_interrupt = 1;
2241 wake_up(&prtd->wait_for_stream_avail);
2242 prtd->next_stream = 0;
2243 }
2244 if (atomic_read(&prtd->eos)) {
2245 pr_debug("%s: interrupt eos wait queues", __func__);
2246 /*
2247 * Gapless playback does not wait for eos, do not set
2248 * cmd_int and do not wake up eos_wait during gapless
2249 * transition
2250 */
2251 if (!prtd->gapless_state.gapless_transition) {
2252 prtd->cmd_interrupt = 1;
2253 wake_up(&prtd->eos_wait);
2254 }
2255 atomic_set(&prtd->eos, 0);
2256 }
2257 if (atomic_read(&prtd->drain)) {
2258 pr_debug("%s: interrupt drain wait queues", __func__);
2259 prtd->cmd_interrupt = 1;
2260 prtd->drain_ready = 1;
2261 wake_up(&prtd->drain_wait);
2262 atomic_set(&prtd->drain, 0);
2263 }
2264 prtd->last_buffer = 0;
2265 prtd->cmd_ack = 0;
2266 if (!prtd->gapless_state.gapless_transition) {
2267 pr_debug("issue CMD_FLUSH stream_id %d\n", stream_id);
2268 spin_unlock_irqrestore(&prtd->lock, flags);
2269 q6asm_stream_cmd(
2270 prtd->audio_client, CMD_FLUSH, stream_id);
2271 spin_lock_irqsave(&prtd->lock, flags);
2272 } else {
2273 prtd->first_buffer = 0;
2274 }
2275 /* FIXME. only reset if flush was successful */
2276 prtd->byte_offset = 0;
2277 prtd->copied_total = 0;
2278 prtd->app_pointer = 0;
2279 prtd->bytes_received = 0;
2280 prtd->bytes_sent = 0;
2281 prtd->marker_timestamp = 0;
2282
2283 atomic_set(&prtd->xrun, 0);
2284 spin_unlock_irqrestore(&prtd->lock, flags);
2285 break;
2286 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2287 pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH transition %d\n",
2288 prtd->gapless_state.gapless_transition);
2289 if (!prtd->gapless_state.gapless_transition) {
2290 pr_debug("issue CMD_PAUSE stream_id %d\n",
2291 ac->stream_id);
2292 q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
2293 atomic_set(&prtd->start, 0);
2294 }
2295 break;
2296 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2297 pr_debug("SNDRV_PCM_TRIGGER_PAUSE_RELEASE transition %d\n",
2298 prtd->gapless_state.gapless_transition);
2299 if (!prtd->gapless_state.gapless_transition) {
2300 atomic_set(&prtd->start, 1);
2301 q6asm_run_nowait(prtd->audio_client, prtd->run_mode,
2302 0, 0);
2303 }
2304 break;
2305 case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
2306 pr_debug("%s: SND_COMPR_TRIGGER_PARTIAL_DRAIN\n", __func__);
2307 if (!prtd->gapless_state.use_dsp_gapless_mode) {
2308 pr_debug("%s: set partial drain as drain\n", __func__);
2309 cmd = SND_COMPR_TRIGGER_DRAIN;
2310 }
2311 case SND_COMPR_TRIGGER_DRAIN:
2312 pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__);
2313 /* Make sure all the data is sent to DSP before sending EOS */
2314 spin_lock_irqsave(&prtd->lock, flags);
2315
2316 if (!atomic_read(&prtd->start)) {
2317 pr_err("%s: stream is not in started state\n",
2318 __func__);
2319 rc = -EPERM;
2320 spin_unlock_irqrestore(&prtd->lock, flags);
2321 break;
2322 }
2323 if (prtd->bytes_received > prtd->copied_total) {
2324 pr_debug("%s: wait till all the data is sent to dsp\n",
2325 __func__);
2326 rc = msm_compr_drain_buffer(prtd, &flags);
2327 if (rc || !atomic_read(&prtd->start)) {
2328 if (rc != -ENETRESET)
2329 rc = -EINTR;
2330 spin_unlock_irqrestore(&prtd->lock, flags);
2331 break;
2332 }
2333 /*
2334 * FIXME: Bug.
2335 * Write(32767)
2336 * Start
2337 * Drain <- Indefinite wait
2338 * sol1 : if (prtd->copied_total) then wait?
2339 * sol2 : (prtd->cmd_interrupt || prtd->drain_ready ||
2340 * atomic_read(xrun)
2341 */
2342 bytes_to_write = prtd->bytes_received
2343 - prtd->copied_total;
2344 WARN(bytes_to_write > runtime->fragment_size,
2345 "last write %d cannot be > than fragment_size",
2346 bytes_to_write);
2347
2348 if (bytes_to_write > 0) {
2349 pr_debug("%s: send %d partial bytes at the end",
2350 __func__, bytes_to_write);
2351 atomic_set(&prtd->xrun, 0);
2352 prtd->last_buffer = 1;
2353 msm_compr_send_buffer(prtd);
2354 }
2355 }
2356
2357 if ((cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN) &&
2358 (prtd->gapless_state.set_next_stream_id)) {
2359 /* wait for the last buffer to be returned */
2360
2361 if (prtd->last_buffer) {
2362 pr_debug("%s: last buffer drain\n", __func__);
2363 rc = msm_compr_drain_buffer(prtd, &flags);
2364 if (rc || !atomic_read(&prtd->start)) {
2365 spin_unlock_irqrestore(&prtd->lock,
2366 flags);
2367 break;
2368 }
2369 }
2370 /* send EOS */
2371 prtd->eos_ack = 0;
2372 atomic_set(&prtd->eos, 1);
2373 pr_debug("issue CMD_EOS stream_id %d\n", ac->stream_id);
2374 q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
2375 pr_info("PARTIAL DRAIN, do not wait for EOS ack\n");
2376
2377 /* send a zero length buffer */
2378 atomic_set(&prtd->xrun, 0);
2379 msm_compr_send_buffer(prtd);
2380
2381 /* wait for the zero length buffer to be returned */
2382 pr_debug("%s: zero length buffer drain\n", __func__);
2383 rc = msm_compr_drain_buffer(prtd, &flags);
2384 if (rc || !atomic_read(&prtd->start)) {
2385 spin_unlock_irqrestore(&prtd->lock, flags);
2386 break;
2387 }
2388
2389 /* sleep for additional duration partial drain */
2390 atomic_set(&prtd->drain, 1);
2391 prtd->drain_ready = 0;
2392 pr_debug("%s, additional sleep: %d\n", __func__,
2393 prtd->partial_drain_delay);
2394 spin_unlock_irqrestore(&prtd->lock, flags);
2395 rc = wait_event_timeout(prtd->drain_wait,
2396 prtd->drain_ready || prtd->cmd_interrupt,
2397 msecs_to_jiffies(prtd->partial_drain_delay));
2398 pr_debug("%s: out of additional wait for low sample rate\n",
2399 __func__);
2400 spin_lock_irqsave(&prtd->lock, flags);
2401 if (prtd->cmd_interrupt) {
2402 pr_debug("%s: additional wait interrupted by flush)\n",
2403 __func__);
2404 rc = -EINTR;
2405 prtd->cmd_interrupt = 0;
2406 spin_unlock_irqrestore(&prtd->lock, flags);
2407 break;
2408 }
2409
2410 /* move to next stream and reset vars */
2411 pr_debug("%s: Moving to next stream in gapless\n",
2412 __func__);
2413 ac->stream_id = NEXT_STREAM_ID(ac->stream_id);
2414 prtd->byte_offset = 0;
2415 prtd->app_pointer = 0;
2416 prtd->first_buffer = 1;
2417 prtd->last_buffer = 0;
2418 /*
2419 * Set gapless transition flag only if EOS hasn't been
2420 * acknowledged already.
2421 */
2422 if (atomic_read(&prtd->eos))
2423 prtd->gapless_state.gapless_transition = 1;
2424 prtd->marker_timestamp = 0;
2425
2426 /*
2427 * Don't reset these as these vars map to
2428 * total_bytes_transferred and total_bytes_available
2429 * directly, only total_bytes_transferred will be
2430 * updated in the next avail() ioctl
2431 * prtd->copied_total = 0;
2432 * prtd->bytes_received = 0;
2433 */
2434 atomic_set(&prtd->drain, 0);
2435 atomic_set(&prtd->xrun, 1);
2436 pr_debug("%s: issue CMD_RUN", __func__);
2437 q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
2438 spin_unlock_irqrestore(&prtd->lock, flags);
2439 break;
2440 }
2441 /*
2442 * moving to next stream failed, so reset the gapless state
2443 * set next stream id for the same session so that the same
2444 * stream can be used for gapless playback
2445 */
2446 prtd->gapless_state.set_next_stream_id = false;
2447 prtd->gapless_state.gapless_transition = 0;
2448 pr_debug("%s:CMD_EOS stream_id %d\n", __func__, ac->stream_id);
2449
2450 prtd->eos_ack = 0;
2451 atomic_set(&prtd->eos, 1);
2452 q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
2453
2454 spin_unlock_irqrestore(&prtd->lock, flags);
2455
2456
2457 /* Wait indefinitely for DRAIN. Flush can also signal this*/
2458 rc = wait_event_interruptible(prtd->eos_wait,
2459 (prtd->eos_ack ||
2460 prtd->cmd_interrupt ||
2461 atomic_read(&prtd->error)));
2462
2463 if (rc < 0)
2464 pr_err("%s: EOS wait failed\n", __func__);
2465
2466 pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait for EOS\n",
2467 __func__);
2468
2469 if (prtd->cmd_interrupt)
2470 rc = -EINTR;
2471
2472 if (atomic_read(&prtd->error)) {
2473 pr_err("%s: Got RESET EVENTS notification, return\n",
2474 __func__);
2475 rc = -ENETRESET;
2476 }
2477
2478 /*FIXME : what if a flush comes while PC is here */
2479 if (rc == 0) {
2480 /*
2481 * Failed to open second stream in DSP for gapless
2482 * so prepare the current stream in session
2483 * for gapless playback
2484 */
2485 spin_lock_irqsave(&prtd->lock, flags);
2486 pr_debug("%s:issue CMD_PAUSE stream_id %d",
2487 __func__, ac->stream_id);
2488 q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
2489 prtd->cmd_ack = 0;
2490 spin_unlock_irqrestore(&prtd->lock, flags);
2491
2492 /*
2493 * Cache this time as last known time
2494 */
2495 if (pdata->use_legacy_api)
2496 q6asm_get_session_time_legacy(
2497 prtd->audio_client,
2498 &prtd->marker_timestamp);
2499 else
2500 q6asm_get_session_time(prtd->audio_client,
2501 &prtd->marker_timestamp);
2502
2503 spin_lock_irqsave(&prtd->lock, flags);
2504 /*
2505 * Don't reset these as these vars map to
2506 * total_bytes_transferred and total_bytes_available.
2507 * Just total_bytes_transferred will be updated
2508 * in the next avail() ioctl.
2509 * prtd->copied_total = 0;
2510 * prtd->bytes_received = 0;
2511 * do not reset prtd->bytes_sent as well as the same
2512 * session is used for gapless playback
2513 */
2514 prtd->byte_offset = 0;
2515
2516 prtd->app_pointer = 0;
2517 prtd->first_buffer = 1;
2518 prtd->last_buffer = 0;
2519 atomic_set(&prtd->drain, 0);
2520 atomic_set(&prtd->xrun, 1);
2521 spin_unlock_irqrestore(&prtd->lock, flags);
2522
2523 pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
2524 __func__, ac->stream_id);
2525 q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
2526
2527 q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
2528 }
2529 prtd->cmd_interrupt = 0;
2530 break;
2531 case SND_COMPR_TRIGGER_NEXT_TRACK:
2532 if (!prtd->gapless_state.use_dsp_gapless_mode) {
2533 pr_debug("%s: ignore trigger next track\n", __func__);
2534 rc = 0;
2535 break;
2536 }
2537 pr_debug("%s: SND_COMPR_TRIGGER_NEXT_TRACK\n", __func__);
2538 spin_lock_irqsave(&prtd->lock, flags);
2539 rc = 0;
2540 /* next stream in gapless */
2541 stream_id = NEXT_STREAM_ID(ac->stream_id);
2542 /*
2543 * Wait if stream 1 has not completed before honoring next
2544 * track for stream 3. Scenario happens if second clip is
2545 * small and fills in one buffer so next track will be
2546 * called immediately.
2547 */
2548 stream_index = STREAM_ARRAY_INDEX(stream_id);
2549 if (stream_index >= MAX_NUMBER_OF_STREAMS ||
2550 stream_index < 0) {
2551 pr_err("%s: Invalid stream index: %d", __func__,
2552 stream_index);
2553 spin_unlock_irqrestore(&prtd->lock, flags);
2554 rc = -EINVAL;
2555 break;
2556 }
2557
2558 if (prtd->gapless_state.stream_opened[stream_index]) {
2559 if (prtd->gapless_state.gapless_transition) {
2560 rc = msm_compr_wait_for_stream_avail(prtd,
2561 &flags);
2562 } else {
2563 /*
2564 * If session is already opened break out if
2565 * the state is not gapless transition. This
2566 * is when seek happens after the last buffer
2567 * is sent to the driver. Next track would be
2568 * called again after last buffer is sent.
2569 */
2570 pr_debug("next session is in opened state\n");
2571 spin_unlock_irqrestore(&prtd->lock, flags);
2572 break;
2573 }
2574 }
2575 spin_unlock_irqrestore(&prtd->lock, flags);
2576 if (rc < 0) {
2577 /*
2578 * if return type EINTR then reset to zero. Tiny
2579 * compress treats EINTR as error and prevents PARTIAL
2580 * DRAIN. EINTR is not an error. wait for stream avail
2581 * is interrupted by some other command like FLUSH.
2582 */
2583 if (rc == -EINTR) {
2584 pr_debug("%s: EINTR reset rc to 0\n", __func__);
2585 rc = 0;
2586 }
2587 break;
2588 }
2589
2590 if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE)
2591 bits_per_sample = 24;
2592 else if (prtd->codec_param.codec.format ==
2593 SNDRV_PCM_FORMAT_S32_LE)
2594 bits_per_sample = 32;
2595
2596 pr_debug("%s: open_write stream_id %d bits_per_sample %d",
2597 __func__, stream_id, bits_per_sample);
2598 rc = q6asm_stream_open_write_v4(prtd->audio_client,
2599 prtd->codec, bits_per_sample,
2600 stream_id,
2601 prtd->gapless_state.use_dsp_gapless_mode);
2602 if (rc < 0) {
2603 pr_err("%s: Session out open failed for gapless\n",
2604 __func__);
2605 break;
2606 }
2607
2608 spin_lock_irqsave(&prtd->lock, flags);
2609 prtd->gapless_state.stream_opened[stream_index] = 1;
2610 prtd->gapless_state.set_next_stream_id = true;
2611 spin_unlock_irqrestore(&prtd->lock, flags);
2612
2613 rc = msm_compr_send_media_format_block(cstream,
2614 stream_id, false);
2615 if (rc < 0) {
2616 pr_err("%s, failed to send media format block\n",
2617 __func__);
2618 break;
2619 }
2620 msm_compr_send_dec_params(cstream, pdata->dec_params[fe_id],
2621 stream_id);
2622 break;
2623 }
2624
2625 return rc;
2626}
2627
2628static int msm_compr_pointer(struct snd_compr_stream *cstream,
2629 struct snd_compr_tstamp *arg)
2630{
2631 struct snd_compr_runtime *runtime = cstream->runtime;
2632 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
2633 struct msm_compr_audio *prtd = runtime->private_data;
2634 struct msm_compr_pdata *pdata = NULL;
2635 struct snd_compr_tstamp tstamp;
2636 uint64_t timestamp = 0;
2637 int rc = 0, first_buffer;
2638 unsigned long flags;
2639 uint32_t gapless_transition;
2640
2641 pdata = snd_soc_platform_get_drvdata(rtd->platform);
2642 pr_debug("%s\n", __func__);
2643 memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
2644
2645 spin_lock_irqsave(&prtd->lock, flags);
2646 tstamp.sampling_rate = prtd->sample_rate;
2647 tstamp.byte_offset = prtd->byte_offset;
2648 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2649 tstamp.copied_total = prtd->copied_total;
2650 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2651 tstamp.copied_total = prtd->received_total;
2652 first_buffer = prtd->first_buffer;
2653 if (atomic_read(&prtd->error)) {
Vatsal Bucha0527c562017-10-04 20:38:49 +05302654 pr_err_ratelimited("%s Got RESET EVENTS notification, return error\n",
2655 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302656 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2657 runtime->total_bytes_transferred = tstamp.copied_total;
2658 else
2659 runtime->total_bytes_available = tstamp.copied_total;
2660 tstamp.pcm_io_frames = 0;
2661 memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
2662 spin_unlock_irqrestore(&prtd->lock, flags);
2663 return -ENETRESET;
2664 }
2665 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
2666
2667 gapless_transition = prtd->gapless_state.gapless_transition;
2668 spin_unlock_irqrestore(&prtd->lock, flags);
2669 if (gapless_transition)
2670 pr_debug("%s session time in gapless transition",
2671 __func__);
2672 /*
2673 *- Do not query if no buffer has been given.
2674 *- Do not query on a gapless transition.
2675 * Playback for the 2nd stream can start (thus returning time
2676 * starting from 0) before the driver knows about EOS of first
2677 * stream.
2678 */
2679 if (!first_buffer || gapless_transition) {
2680
2681 if (pdata->use_legacy_api)
2682 rc = q6asm_get_session_time_legacy(
2683 prtd->audio_client, &prtd->marker_timestamp);
2684 else
2685 rc = q6asm_get_session_time(
2686 prtd->audio_client, &prtd->marker_timestamp);
2687 if (rc < 0) {
2688 pr_err("%s: Get Session Time return =%lld\n",
2689 __func__, timestamp);
2690 if (atomic_read(&prtd->error))
2691 return -ENETRESET;
2692 else
2693 return -EAGAIN;
2694 }
2695 }
2696 } else {
2697 spin_unlock_irqrestore(&prtd->lock, flags);
2698 }
2699 timestamp = prtd->marker_timestamp;
2700
2701 /* DSP returns timestamp in usec */
2702 pr_debug("%s: timestamp = %lld usec\n", __func__, timestamp);
2703 timestamp *= prtd->sample_rate;
2704 tstamp.pcm_io_frames = (snd_pcm_uframes_t)div64_u64(timestamp, 1000000);
2705 memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
2706
2707 return 0;
2708}
2709
2710static int msm_compr_ack(struct snd_compr_stream *cstream,
2711 size_t count)
2712{
2713 struct snd_compr_runtime *runtime = cstream->runtime;
2714 struct msm_compr_audio *prtd = runtime->private_data;
2715 void *src, *dstn;
2716 size_t copy;
2717 unsigned long flags;
2718
2719 WARN(1, "This path is untested");
2720 return -EINVAL;
2721
2722 pr_debug("%s: count = %zd\n", __func__, count);
2723 if (!prtd->buffer) {
2724 pr_err("%s: Buffer is not allocated yet ??\n", __func__);
2725 return -EINVAL;
2726 }
2727 src = runtime->buffer + prtd->app_pointer;
2728 dstn = prtd->buffer + prtd->app_pointer;
2729 if (count < prtd->buffer_size - prtd->app_pointer) {
2730 memcpy(dstn, src, count);
2731 prtd->app_pointer += count;
2732 } else {
2733 copy = prtd->buffer_size - prtd->app_pointer;
2734 memcpy(dstn, src, copy);
2735 memcpy(prtd->buffer, runtime->buffer, count - copy);
2736 prtd->app_pointer = count - copy;
2737 }
2738
2739 /*
2740 * If the stream is started and all the bytes received were
2741 * copied to DSP, the newly received bytes should be
2742 * sent right away
2743 */
2744 spin_lock_irqsave(&prtd->lock, flags);
2745
2746 if (atomic_read(&prtd->start) &&
2747 prtd->bytes_received == prtd->copied_total) {
2748 prtd->bytes_received += count;
2749 msm_compr_send_buffer(prtd);
2750 } else
2751 prtd->bytes_received += count;
2752
2753 spin_unlock_irqrestore(&prtd->lock, flags);
2754
2755 return 0;
2756}
2757
2758static int msm_compr_playback_copy(struct snd_compr_stream *cstream,
2759 char __user *buf, size_t count)
2760{
2761 struct snd_compr_runtime *runtime = cstream->runtime;
2762 struct msm_compr_audio *prtd = runtime->private_data;
2763 void *dstn;
2764 size_t copy;
2765 uint64_t bytes_available = 0;
2766 unsigned long flags;
2767
2768 pr_debug("%s: count = %zd\n", __func__, count);
2769 if (!prtd->buffer) {
2770 pr_err("%s: Buffer is not allocated yet ??", __func__);
2771 return 0;
2772 }
2773
2774 spin_lock_irqsave(&prtd->lock, flags);
2775 if (atomic_read(&prtd->error)) {
2776 pr_err("%s Got RESET EVENTS notification", __func__);
2777 spin_unlock_irqrestore(&prtd->lock, flags);
2778 return -ENETRESET;
2779 }
2780 spin_unlock_irqrestore(&prtd->lock, flags);
2781
2782 dstn = prtd->buffer + prtd->app_pointer;
2783 if (count < prtd->buffer_size - prtd->app_pointer) {
2784 if (copy_from_user(dstn, buf, count))
2785 return -EFAULT;
2786 prtd->app_pointer += count;
2787 } else {
2788 copy = prtd->buffer_size - prtd->app_pointer;
2789 if (copy_from_user(dstn, buf, copy))
2790 return -EFAULT;
2791 if (copy_from_user(prtd->buffer, buf + copy, count - copy))
2792 return -EFAULT;
2793 prtd->app_pointer = count - copy;
2794 }
2795
2796 /*
2797 * If stream is started and there has been an xrun,
2798 * since the available bytes fits fragment_size, copy the data
2799 * right away.
2800 */
2801 spin_lock_irqsave(&prtd->lock, flags);
2802 prtd->bytes_received += count;
2803 if (atomic_read(&prtd->start)) {
2804 if (atomic_read(&prtd->xrun)) {
2805 pr_debug("%s: in xrun, count = %zd\n", __func__, count);
2806 bytes_available = prtd->bytes_received -
2807 prtd->copied_total;
2808 if (bytes_available >= runtime->fragment_size) {
2809 pr_debug("%s: handle xrun, bytes_to_write = %llu\n",
2810 __func__, bytes_available);
2811 atomic_set(&prtd->xrun, 0);
2812 msm_compr_send_buffer(prtd);
2813 } /* else not sufficient data */
2814 } /* writes will continue on the next write_done */
2815 }
2816
2817 spin_unlock_irqrestore(&prtd->lock, flags);
2818
2819 return count;
2820}
2821
2822static int msm_compr_capture_copy(struct snd_compr_stream *cstream,
2823 char __user *buf, size_t count)
2824{
2825 struct snd_compr_runtime *runtime = cstream->runtime;
2826 struct msm_compr_audio *prtd = runtime->private_data;
2827 void *source;
2828 unsigned long flags;
2829
2830 pr_debug("%s: count = %zd\n", __func__, count);
2831 if (!prtd->buffer) {
2832 pr_err("%s: Buffer is not allocated yet ??", __func__);
2833 return 0;
2834 }
2835
2836 spin_lock_irqsave(&prtd->lock, flags);
2837 if (atomic_read(&prtd->error)) {
2838 pr_err("%s Got RESET EVENTS notification", __func__);
2839 spin_unlock_irqrestore(&prtd->lock, flags);
2840 return -ENETRESET;
2841 }
2842
2843 source = prtd->buffer + prtd->app_pointer;
2844 /* check if we have requested amount of data to copy to user*/
2845 if (count <= prtd->received_total - prtd->bytes_copied) {
2846 spin_unlock_irqrestore(&prtd->lock, flags);
2847 if (copy_to_user(buf, source, count)) {
2848 pr_err("copy_to_user failed");
2849 return -EFAULT;
2850 }
2851 spin_lock_irqsave(&prtd->lock, flags);
2852 prtd->app_pointer += count;
2853 if (prtd->app_pointer >= prtd->buffer_size)
2854 prtd->app_pointer -= prtd->buffer_size;
2855 prtd->bytes_copied += count;
2856 }
2857 msm_compr_read_buffer(prtd);
2858
2859 spin_unlock_irqrestore(&prtd->lock, flags);
2860 return count;
2861}
2862
2863static int msm_compr_copy(struct snd_compr_stream *cstream,
2864 char __user *buf, size_t count)
2865{
2866 int ret = 0;
2867
2868 pr_debug(" In %s\n", __func__);
2869 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2870 ret = msm_compr_playback_copy(cstream, buf, count);
2871 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2872 ret = msm_compr_capture_copy(cstream, buf, count);
2873 return ret;
2874}
2875
2876static int msm_compr_get_caps(struct snd_compr_stream *cstream,
2877 struct snd_compr_caps *arg)
2878{
2879 struct snd_compr_runtime *runtime = cstream->runtime;
2880 struct msm_compr_audio *prtd = runtime->private_data;
2881 int ret = 0;
2882
2883 pr_debug("%s\n", __func__);
2884 if ((arg != NULL) && (prtd != NULL)) {
2885 memcpy(arg, &prtd->compr_cap, sizeof(struct snd_compr_caps));
2886 } else {
2887 ret = -EINVAL;
2888 pr_err("%s: arg (0x%pK), prtd (0x%pK)\n", __func__, arg, prtd);
2889 }
2890
2891 return ret;
2892}
2893
2894static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
2895 struct snd_compr_codec_caps *codec)
2896{
2897 pr_debug("%s\n", __func__);
2898
2899 switch (codec->codec) {
2900 case SND_AUDIOCODEC_MP3:
2901 codec->num_descriptors = 2;
2902 codec->descriptor[0].max_ch = 2;
2903 memcpy(codec->descriptor[0].sample_rates,
2904 supported_sample_rates,
2905 sizeof(supported_sample_rates));
2906 codec->descriptor[0].num_sample_rates =
2907 sizeof(supported_sample_rates)/sizeof(unsigned int);
2908 codec->descriptor[0].bit_rate[0] = 320; /* 320kbps */
2909 codec->descriptor[0].bit_rate[1] = 128;
2910 codec->descriptor[0].num_bitrates = 2;
2911 codec->descriptor[0].profiles = 0;
2912 codec->descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO;
2913 codec->descriptor[0].formats = 0;
2914 break;
2915 case SND_AUDIOCODEC_AAC:
2916 codec->num_descriptors = 2;
2917 codec->descriptor[1].max_ch = 2;
2918 memcpy(codec->descriptor[1].sample_rates,
2919 supported_sample_rates,
2920 sizeof(supported_sample_rates));
2921 codec->descriptor[1].num_sample_rates =
2922 sizeof(supported_sample_rates)/sizeof(unsigned int);
2923 codec->descriptor[1].bit_rate[0] = 320; /* 320kbps */
2924 codec->descriptor[1].bit_rate[1] = 128;
2925 codec->descriptor[1].num_bitrates = 2;
2926 codec->descriptor[1].profiles = 0;
2927 codec->descriptor[1].modes = 0;
2928 codec->descriptor[1].formats =
2929 (SND_AUDIOSTREAMFORMAT_MP4ADTS |
2930 SND_AUDIOSTREAMFORMAT_RAW);
2931 break;
2932 case SND_AUDIOCODEC_AC3:
2933 case SND_AUDIOCODEC_EAC3:
2934 case SND_AUDIOCODEC_FLAC:
2935 case SND_AUDIOCODEC_VORBIS:
2936 case SND_AUDIOCODEC_ALAC:
2937 case SND_AUDIOCODEC_APE:
2938 case SND_AUDIOCODEC_DTS:
2939 case SND_AUDIOCODEC_DSD:
2940 case SND_AUDIOCODEC_TRUEHD:
2941 case SND_AUDIOCODEC_IEC61937:
2942 case SND_AUDIOCODEC_APTX:
2943 break;
2944 default:
2945 pr_err("%s: Unsupported audio codec %d\n",
2946 __func__, codec->codec);
2947 return -EINVAL;
2948 }
2949
2950 return 0;
2951}
2952
2953static int msm_compr_set_metadata(struct snd_compr_stream *cstream,
2954 struct snd_compr_metadata *metadata)
2955{
2956 struct msm_compr_audio *prtd;
2957 struct audio_client *ac;
2958 pr_debug("%s\n", __func__);
2959
2960 if (!metadata || !cstream)
2961 return -EINVAL;
2962
2963 prtd = cstream->runtime->private_data;
2964 if (!prtd || !prtd->audio_client) {
2965 pr_err("%s: prtd or audio client is NULL\n", __func__);
2966 return -EINVAL;
2967 }
2968
2969 if (((metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) ||
2970 (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY)) &&
2971 (prtd->compr_passthr != LEGACY_PCM)) {
2972 pr_debug("%s: No trailing silence for compress_type[%d]\n",
2973 __func__, prtd->compr_passthr);
2974 return 0;
2975 }
2976
2977 ac = prtd->audio_client;
2978 if (metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) {
2979 pr_debug("%s, got encoder padding %u",
2980 __func__, metadata->value[0]);
2981 prtd->gapless_state.trailing_samples_drop = metadata->value[0];
2982 } else if (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY) {
2983 pr_debug("%s, got encoder delay %u",
2984 __func__, metadata->value[0]);
2985 prtd->gapless_state.initial_samples_drop = metadata->value[0];
2986 } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) {
2987 return msm_compr_set_render_mode(prtd, metadata->value[0]);
2988 } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) {
2989 return msm_compr_set_clk_rec_mode(ac, metadata->value[0]);
2990 } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) {
2991 return msm_compr_set_render_window(
2992 ac,
2993 metadata->value[0],
2994 metadata->value[1],
2995 metadata->value[2],
2996 metadata->value[3]);
2997 } else if (metadata->key == SNDRV_COMPRESS_START_DELAY) {
2998 prtd->start_delay_lsw = metadata->value[0];
2999 prtd->start_delay_msw = metadata->value[1];
3000 } else if (metadata->key ==
3001 SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK) {
3002 return msm_compr_enable_adjust_session_clock(ac,
3003 metadata->value[0]);
3004 } else if (metadata->key == SNDRV_COMPRESS_ADJUST_SESSION_CLOCK) {
3005 return msm_compr_adjust_session_clock(ac,
3006 metadata->value[0],
3007 metadata->value[1]);
3008 }
3009
3010 return 0;
3011}
3012
3013static int msm_compr_get_metadata(struct snd_compr_stream *cstream,
3014 struct snd_compr_metadata *metadata)
3015{
3016 struct msm_compr_audio *prtd;
3017 struct audio_client *ac;
3018 int ret = -EINVAL;
3019
3020 pr_debug("%s\n", __func__);
3021
3022 if (!metadata || !cstream || !cstream->runtime)
3023 return ret;
3024
3025 if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) {
3026 pr_err("%s, unsupported key %d\n", __func__, metadata->key);
3027 return ret;
3028 }
3029
3030 prtd = cstream->runtime->private_data;
3031 if (!prtd || !prtd->audio_client) {
3032 pr_err("%s: prtd or audio client is NULL\n", __func__);
3033 return ret;
3034 }
3035
3036 ac = prtd->audio_client;
3037 ret = q6asm_get_path_delay(prtd->audio_client);
3038 if (ret) {
3039 pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret);
3040 return ret;
3041 }
3042
3043 pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay);
3044
3045 metadata->value[0] = ac->path_delay;
3046
3047 return ret;
3048}
3049
3050
3051static int msm_compr_set_next_track_param(struct snd_compr_stream *cstream,
3052 union snd_codec_options *codec_options)
3053{
3054 struct msm_compr_audio *prtd;
3055 struct audio_client *ac;
3056 int ret = 0;
3057
3058 if (!codec_options || !cstream)
3059 return -EINVAL;
3060
3061 prtd = cstream->runtime->private_data;
3062 if (!prtd || !prtd->audio_client) {
3063 pr_err("%s: prtd or audio client is NULL\n", __func__);
3064 return -EINVAL;
3065 }
3066
3067 ac = prtd->audio_client;
3068
3069 pr_debug("%s: got codec options for codec type %u",
3070 __func__, prtd->codec);
3071 switch (prtd->codec) {
3072 case FORMAT_WMA_V9:
3073 case FORMAT_WMA_V10PRO:
3074 case FORMAT_FLAC:
3075 case FORMAT_VORBIS:
3076 case FORMAT_ALAC:
3077 case FORMAT_APE:
3078 memcpy(&(prtd->gapless_state.codec_options),
3079 codec_options,
3080 sizeof(union snd_codec_options));
3081 ret = msm_compr_send_media_format_block(cstream,
3082 ac->stream_id, true);
3083 if (ret < 0) {
3084 pr_err("%s: failed to send media format block\n",
3085 __func__);
3086 }
3087 break;
3088
3089 default:
3090 pr_debug("%s: Ignore sending CMD Format block\n",
3091 __func__);
3092 break;
3093 }
3094
3095 return ret;
3096}
3097
3098static int msm_compr_volume_put(struct snd_kcontrol *kcontrol,
3099 struct snd_ctl_elem_value *ucontrol)
3100{
3101 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3102 unsigned long fe_id = kcontrol->private_value;
3103 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3104 snd_soc_component_get_drvdata(comp);
3105 struct snd_compr_stream *cstream = NULL;
3106 uint32_t *volume = NULL;
3107
3108 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3109 pr_err("%s Received out of bounds fe_id %lu\n",
3110 __func__, fe_id);
3111 return -EINVAL;
3112 }
3113
3114 cstream = pdata->cstream[fe_id];
3115 volume = pdata->volume[fe_id];
3116
3117 volume[0] = ucontrol->value.integer.value[0];
3118 volume[1] = ucontrol->value.integer.value[1];
3119 pr_debug("%s: fe_id %lu left_vol %d right_vol %d\n",
3120 __func__, fe_id, volume[0], volume[1]);
3121 if (cstream)
3122 msm_compr_set_volume(cstream, volume[0], volume[1]);
3123 return 0;
3124}
3125
3126static int msm_compr_volume_get(struct snd_kcontrol *kcontrol,
3127 struct snd_ctl_elem_value *ucontrol)
3128{
3129 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3130 unsigned long fe_id = kcontrol->private_value;
3131
3132 struct msm_compr_pdata *pdata =
3133 snd_soc_component_get_drvdata(comp);
3134 uint32_t *volume = NULL;
3135
3136 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3137 pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id);
3138 return -EINVAL;
3139 }
3140
3141 volume = pdata->volume[fe_id];
3142 pr_debug("%s: fe_id %lu\n", __func__, fe_id);
3143 ucontrol->value.integer.value[0] = volume[0];
3144 ucontrol->value.integer.value[1] = volume[1];
3145
3146 return 0;
3147}
3148
3149static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
3150 struct snd_ctl_elem_value *ucontrol)
3151{
3152 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3153 unsigned long fe_id = kcontrol->private_value;
3154 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3155 snd_soc_component_get_drvdata(comp);
3156 struct msm_compr_audio_effects *audio_effects = NULL;
3157 struct snd_compr_stream *cstream = NULL;
3158 struct msm_compr_audio *prtd = NULL;
3159 long *values = &(ucontrol->value.integer.value[0]);
3160 int effects_module;
3161
3162 pr_debug("%s\n", __func__);
3163 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3164 pr_err("%s Received out of bounds fe_id %lu\n",
3165 __func__, fe_id);
3166 return -EINVAL;
3167 }
3168 cstream = pdata->cstream[fe_id];
3169 audio_effects = pdata->audio_effects[fe_id];
3170 if (!cstream || !audio_effects) {
3171 pr_err("%s: stream or effects inactive\n", __func__);
3172 return -EINVAL;
3173 }
3174 prtd = cstream->runtime->private_data;
3175 if (!prtd) {
3176 pr_err("%s: cannot set audio effects\n", __func__);
3177 return -EINVAL;
3178 }
3179 if (prtd->compr_passthr != LEGACY_PCM) {
3180 pr_debug("%s: No effects for compr_type[%d]\n",
3181 __func__, prtd->compr_passthr);
3182 return 0;
3183 }
3184 pr_debug("%s: Effects supported for compr_type[%d]\n",
3185 __func__, prtd->compr_passthr);
3186
3187 effects_module = *values++;
3188 switch (effects_module) {
3189 case VIRTUALIZER_MODULE:
3190 pr_debug("%s: VIRTUALIZER_MODULE\n", __func__);
3191 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3192 prtd->audio_client->topology))
3193 msm_audio_effects_virtualizer_handler(
3194 prtd->audio_client,
3195 &(audio_effects->virtualizer),
3196 values);
3197 break;
3198 case REVERB_MODULE:
3199 pr_debug("%s: REVERB_MODULE\n", __func__);
3200 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3201 prtd->audio_client->topology))
3202 msm_audio_effects_reverb_handler(prtd->audio_client,
3203 &(audio_effects->reverb),
3204 values);
3205 break;
3206 case BASS_BOOST_MODULE:
3207 pr_debug("%s: BASS_BOOST_MODULE\n", __func__);
3208 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3209 prtd->audio_client->topology))
3210 msm_audio_effects_bass_boost_handler(prtd->audio_client,
3211 &(audio_effects->bass_boost),
3212 values);
3213 break;
3214 case PBE_MODULE:
3215 pr_debug("%s: PBE_MODULE\n", __func__);
3216 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3217 prtd->audio_client->topology))
3218 msm_audio_effects_pbe_handler(prtd->audio_client,
3219 &(audio_effects->pbe),
3220 values);
3221 break;
3222 case EQ_MODULE:
3223 pr_debug("%s: EQ_MODULE\n", __func__);
3224 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3225 prtd->audio_client->topology))
3226 msm_audio_effects_popless_eq_handler(prtd->audio_client,
3227 &(audio_effects->equalizer),
3228 values);
3229 break;
3230 case SOFT_VOLUME_MODULE:
3231 pr_debug("%s: SOFT_VOLUME_MODULE\n", __func__);
3232 break;
3233 case SOFT_VOLUME2_MODULE:
3234 pr_debug("%s: SOFT_VOLUME2_MODULE\n", __func__);
3235 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3236 prtd->audio_client->topology))
3237 msm_audio_effects_volume_handler_v2(prtd->audio_client,
3238 &(audio_effects->volume),
3239 values, SOFT_VOLUME_INSTANCE_2);
3240 break;
3241 default:
3242 pr_err("%s Invalid effects config module\n", __func__);
3243 return -EINVAL;
3244 }
3245 return 0;
3246}
3247
3248static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
3249 struct snd_ctl_elem_value *ucontrol)
3250{
3251 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3252 unsigned long fe_id = kcontrol->private_value;
3253 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3254 snd_soc_component_get_drvdata(comp);
3255 struct msm_compr_audio_effects *audio_effects = NULL;
3256 struct snd_compr_stream *cstream = NULL;
3257 struct msm_compr_audio *prtd = NULL;
3258
3259 pr_debug("%s\n", __func__);
3260 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3261 pr_err("%s Received out of bounds fe_id %lu\n",
3262 __func__, fe_id);
3263 return -EINVAL;
3264 }
3265 cstream = pdata->cstream[fe_id];
3266 audio_effects = pdata->audio_effects[fe_id];
3267 if (!cstream || !audio_effects) {
3268 pr_err("%s: stream or effects inactive\n", __func__);
3269 return -EINVAL;
3270 }
3271 prtd = cstream->runtime->private_data;
3272 if (!prtd) {
3273 pr_err("%s: cannot set audio effects\n", __func__);
3274 return -EINVAL;
3275 }
3276
3277 return 0;
3278}
3279
3280static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
3281 struct snd_ctl_elem_value *ucontrol)
3282{
3283 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3284 unsigned long fe_id = kcontrol->private_value;
3285 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3286 snd_soc_component_get_drvdata(comp);
3287 struct msm_compr_audio_effects *audio_effects = NULL;
3288 struct snd_compr_stream *cstream = NULL;
3289 struct msm_compr_audio *prtd = NULL;
3290 long *values = &(ucontrol->value.integer.value[0]);
3291
3292 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3293 pr_err("%s Received out of bounds fe_id %lu\n",
3294 __func__, fe_id);
3295 return -EINVAL;
3296 }
3297 cstream = pdata->cstream[fe_id];
3298 audio_effects = pdata->audio_effects[fe_id];
3299 if (!cstream || !audio_effects) {
3300 pr_err("%s: stream or effects inactive\n", __func__);
3301 return -EINVAL;
3302 }
3303 prtd = cstream->runtime->private_data;
3304 if (!prtd) {
3305 pr_err("%s: cannot set audio effects\n", __func__);
3306 return -EINVAL;
3307 }
3308 if (prtd->compr_passthr != LEGACY_PCM) {
3309 pr_err("%s: No effects for compr_type[%d]\n",
3310 __func__, prtd->compr_passthr);
3311 return -EPERM;
3312 }
3313 audio_effects->query.mod_id = (u32)*values++;
3314 audio_effects->query.parm_id = (u32)*values++;
3315 audio_effects->query.size = (u32)*values++;
3316 audio_effects->query.offset = (u32)*values++;
3317 audio_effects->query.device = (u32)*values++;
3318 return 0;
3319}
3320
3321static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
3322 struct snd_ctl_elem_value *ucontrol)
3323{
3324 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3325 unsigned long fe_id = kcontrol->private_value;
3326 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3327 snd_soc_component_get_drvdata(comp);
3328 struct msm_compr_audio_effects *audio_effects = NULL;
3329 struct snd_compr_stream *cstream = NULL;
3330 struct msm_compr_audio *prtd = NULL;
3331 long *values = &(ucontrol->value.integer.value[0]);
3332
3333 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3334 pr_err("%s Received out of bounds fe_id %lu\n",
3335 __func__, fe_id);
3336 return -EINVAL;
3337 }
3338 cstream = pdata->cstream[fe_id];
3339 audio_effects = pdata->audio_effects[fe_id];
3340 if (!cstream || !audio_effects) {
3341 pr_debug("%s: stream or effects inactive\n", __func__);
3342 return -EINVAL;
3343 }
3344 prtd = cstream->runtime->private_data;
3345 if (!prtd) {
3346 pr_err("%s: cannot set audio effects\n", __func__);
3347 return -EINVAL;
3348 }
3349 values[0] = (long)audio_effects->query.mod_id;
3350 values[1] = (long)audio_effects->query.parm_id;
3351 values[2] = (long)audio_effects->query.size;
3352 values[3] = (long)audio_effects->query.offset;
3353 values[4] = (long)audio_effects->query.device;
3354 return 0;
3355}
3356
3357static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
3358 struct msm_compr_dec_params *dec_params,
3359 int stream_id)
3360{
3361
3362 int rc = 0;
3363 struct msm_compr_audio *prtd = NULL;
3364 struct snd_dec_ddp *ddp = &dec_params->ddp_params;
3365
3366 if (!cstream || !dec_params) {
3367 pr_err("%s: stream or dec_params inactive\n", __func__);
3368 rc = -EINVAL;
3369 goto end;
3370 }
3371 prtd = cstream->runtime->private_data;
3372 if (!prtd) {
3373 pr_err("%s: cannot set dec_params\n", __func__);
3374 rc = -EINVAL;
3375 goto end;
3376 }
3377 switch (prtd->codec) {
3378 case FORMAT_MP3:
3379 case FORMAT_MPEG4_AAC:
3380 case FORMAT_TRUEHD:
3381 case FORMAT_IEC61937:
3382 case FORMAT_APTX:
3383 pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
3384 prtd->codec);
3385 break;
3386 case FORMAT_AC3:
3387 case FORMAT_EAC3:
3388 if (prtd->compr_passthr != LEGACY_PCM) {
3389 pr_debug("%s: No DDP param for compr_type[%d]\n",
3390 __func__, prtd->compr_passthr);
3391 break;
3392 }
3393 rc = msm_compr_send_ddp_cfg(prtd->audio_client, ddp, stream_id);
3394 if (rc < 0)
3395 pr_err("%s: DDP CMD CFG failed %d\n", __func__, rc);
3396 break;
3397 default:
3398 break;
3399 }
3400end:
3401 return rc;
3402
3403}
3404static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
3405 struct snd_ctl_elem_value *ucontrol)
3406{
3407 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3408 unsigned long fe_id = kcontrol->private_value;
3409 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3410 snd_soc_component_get_drvdata(comp);
3411 struct msm_compr_dec_params *dec_params = NULL;
3412 struct snd_compr_stream *cstream = NULL;
3413 struct msm_compr_audio *prtd = NULL;
3414 long *values = &(ucontrol->value.integer.value[0]);
3415 int rc = 0;
3416
3417 pr_debug("%s\n", __func__);
3418 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3419 pr_err("%s Received out of bounds fe_id %lu\n",
3420 __func__, fe_id);
3421 rc = -EINVAL;
3422 goto end;
3423 }
3424
3425 cstream = pdata->cstream[fe_id];
3426 dec_params = pdata->dec_params[fe_id];
3427
3428 if (!cstream || !dec_params) {
3429 pr_err("%s: stream or dec_params inactive\n", __func__);
3430 rc = -EINVAL;
3431 goto end;
3432 }
3433 prtd = cstream->runtime->private_data;
3434 if (!prtd) {
3435 pr_err("%s: cannot set dec_params\n", __func__);
3436 rc = -EINVAL;
3437 goto end;
3438 }
3439
3440 switch (prtd->codec) {
3441 case FORMAT_MP3:
3442 case FORMAT_MPEG4_AAC:
3443 case FORMAT_FLAC:
3444 case FORMAT_VORBIS:
3445 case FORMAT_ALAC:
3446 case FORMAT_APE:
3447 case FORMAT_DTS:
3448 case FORMAT_DSD:
3449 case FORMAT_TRUEHD:
3450 case FORMAT_IEC61937:
3451 case FORMAT_APTX:
3452 pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
3453 prtd->codec);
3454 break;
3455 case FORMAT_AC3:
3456 case FORMAT_EAC3: {
3457 struct snd_dec_ddp *ddp = &dec_params->ddp_params;
3458 int cnt;
3459
3460 if (prtd->compr_passthr != LEGACY_PCM) {
3461 pr_debug("%s: No DDP param for compr_type[%d]\n",
3462 __func__, prtd->compr_passthr);
3463 break;
3464 }
3465
3466 ddp->params_length = (*values++);
3467 if (ddp->params_length > DDP_DEC_MAX_NUM_PARAM) {
3468 pr_err("%s: invalid num of params:: %d\n", __func__,
3469 ddp->params_length);
3470 rc = -EINVAL;
3471 goto end;
3472 }
3473 for (cnt = 0; cnt < ddp->params_length; cnt++) {
3474 ddp->params_id[cnt] = *values++;
3475 ddp->params_value[cnt] = *values++;
3476 }
3477 prtd = cstream->runtime->private_data;
3478 if (prtd && prtd->audio_client)
3479 rc = msm_compr_send_dec_params(cstream, dec_params,
3480 prtd->audio_client->stream_id);
3481 break;
3482 }
3483 default:
3484 break;
3485 }
3486end:
3487 pr_debug("%s: ret %d\n", __func__, rc);
3488 return rc;
3489}
3490
3491static int msm_compr_dec_params_get(struct snd_kcontrol *kcontrol,
3492 struct snd_ctl_elem_value *ucontrol)
3493{
3494 /* dummy function */
3495 return 0;
3496}
3497
3498static int msm_compr_playback_app_type_cfg_put(struct snd_kcontrol *kcontrol,
3499 struct snd_ctl_elem_value *ucontrol)
3500{
3501 u64 fe_id = kcontrol->private_value;
3502 int session_type = SESSION_TYPE_RX;
3503 int be_id = ucontrol->value.integer.value[3];
3504 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
3505 int ret = 0;
3506
3507 cfg_data.app_type = ucontrol->value.integer.value[0];
3508 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
3509 if (ucontrol->value.integer.value[2] != 0)
3510 cfg_data.sample_rate = ucontrol->value.integer.value[2];
3511 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n",
3512 __func__, fe_id, session_type, be_id,
3513 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3514 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
3515 be_id, &cfg_data);
3516 if (ret < 0)
3517 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
3518 __func__, ret);
3519
3520 return ret;
3521}
3522
3523static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol,
3524 struct snd_ctl_elem_value *ucontrol)
3525{
3526 u64 fe_id = kcontrol->private_value;
3527 int session_type = SESSION_TYPE_RX;
3528 int be_id = 0;
3529 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
3530 int ret = 0;
3531
3532 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
3533 &be_id, &cfg_data);
3534 if (ret < 0) {
3535 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
3536 __func__, ret);
3537 goto done;
3538 }
3539
3540 ucontrol->value.integer.value[0] = cfg_data.app_type;
3541 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
3542 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
3543 ucontrol->value.integer.value[3] = be_id;
3544 pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
3545 __func__, fe_id, session_type, be_id,
3546 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3547done:
3548 return ret;
3549}
3550
3551static int msm_compr_capture_app_type_cfg_put(struct snd_kcontrol *kcontrol,
3552 struct snd_ctl_elem_value *ucontrol)
3553{
3554 u64 fe_id = kcontrol->private_value;
3555 int session_type = SESSION_TYPE_TX;
3556 int be_id = ucontrol->value.integer.value[3];
3557 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
3558 int ret = 0;
3559
3560 cfg_data.app_type = ucontrol->value.integer.value[0];
3561 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
3562 if (ucontrol->value.integer.value[2] != 0)
3563 cfg_data.sample_rate = ucontrol->value.integer.value[2];
3564 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n",
3565 __func__, fe_id, session_type, be_id,
3566 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3567 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
3568 be_id, &cfg_data);
3569 if (ret < 0)
3570 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
3571 __func__, ret);
3572
3573 return ret;
3574}
3575
3576static int msm_compr_capture_app_type_cfg_get(struct snd_kcontrol *kcontrol,
3577 struct snd_ctl_elem_value *ucontrol)
3578{
3579 u64 fe_id = kcontrol->private_value;
3580 int session_type = SESSION_TYPE_TX;
3581 int be_id = 0;
3582 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
3583 int ret = 0;
3584
3585 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
3586 &be_id, &cfg_data);
3587 if (ret < 0) {
3588 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
3589 __func__, ret);
3590 goto done;
3591 }
3592
3593 ucontrol->value.integer.value[0] = cfg_data.app_type;
3594 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
3595 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
3596 ucontrol->value.integer.value[3] = be_id;
3597 pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
3598 __func__, fe_id, session_type, be_id,
3599 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3600done:
3601 return ret;
3602}
3603
3604static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol,
3605 struct snd_ctl_elem_value *ucontrol)
3606{
3607 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3608 u64 fe_id = kcontrol->private_value;
3609 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3610 snd_soc_component_get_drvdata(comp);
3611 int rc = 0, i;
3612
3613 pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
3614
3615 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3616 pr_err("%s Received out of bounds fe_id %llu\n",
3617 __func__, fe_id);
3618 rc = -EINVAL;
3619 goto end;
3620 }
3621
3622 if (pdata->ch_map[fe_id]) {
3623 pdata->ch_map[fe_id]->set_ch_map = true;
Dieter Lueckingba7644d2018-09-28 15:09:32 +02003624 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303625 pdata->ch_map[fe_id]->channel_map[i] =
3626 (char)(ucontrol->value.integer.value[i]);
3627 } else {
3628 pr_debug("%s: no memory for ch_map, default will be set\n",
3629 __func__);
3630 }
3631end:
3632 pr_debug("%s: ret %d\n", __func__, rc);
3633 return rc;
3634}
3635
3636static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol,
3637 struct snd_ctl_elem_value *ucontrol)
3638{
3639 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3640 u64 fe_id = kcontrol->private_value;
3641 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3642 snd_soc_component_get_drvdata(comp);
3643 int rc = 0, i;
3644
3645 pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
3646 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3647 pr_err("%s: Received out of bounds fe_id %llu\n",
3648 __func__, fe_id);
3649 rc = -EINVAL;
3650 goto end;
3651 }
3652 if (pdata->ch_map[fe_id]) {
Dieter Lueckingba7644d2018-09-28 15:09:32 +02003653 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303654 ucontrol->value.integer.value[i] =
3655 pdata->ch_map[fe_id]->channel_map[i];
3656 }
3657end:
3658 pr_debug("%s: ret %d\n", __func__, rc);
3659 return rc;
3660}
3661
3662static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
3663 struct snd_ctl_elem_value *ucontrol)
3664{
3665 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3666 unsigned long fe_id = kcontrol->private_value;
3667 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3668 snd_soc_component_get_drvdata(comp);
3669 struct snd_compr_stream *cstream = NULL;
3670 struct msm_compr_audio *prtd;
3671 int ret = 0;
3672 struct msm_adsp_event_data *event_data = NULL;
Aditya Bavanari2e3341d2018-02-23 12:58:57 +05303673 uint64_t actual_payload_len = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303674
3675 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3676 pr_err("%s Received invalid fe_id %lu\n",
3677 __func__, fe_id);
3678 ret = -EINVAL;
3679 goto done;
3680 }
3681
3682 cstream = pdata->cstream[fe_id];
3683 if (cstream == NULL) {
3684 pr_err("%s cstream is null\n", __func__);
3685 ret = -EINVAL;
3686 goto done;
3687 }
3688
3689 prtd = cstream->runtime->private_data;
3690 if (!prtd) {
3691 pr_err("%s: prtd is null\n", __func__);
3692 ret = -EINVAL;
3693 goto done;
3694 }
3695
3696 if (prtd->audio_client == NULL) {
3697 pr_err("%s: audio_client is null\n", __func__);
3698 ret = -EINVAL;
3699 goto done;
3700 }
3701
3702 event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
3703 if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
3704 (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
3705 pr_err("%s: invalid event_type=%d",
3706 __func__, event_data->event_type);
3707 ret = -EINVAL;
3708 goto done;
3709 }
3710
Aditya Bavanari2e3341d2018-02-23 12:58:57 +05303711 actual_payload_len = sizeof(struct msm_adsp_event_data) +
3712 event_data->payload_len;
3713 if (actual_payload_len >= U32_MAX) {
3714 pr_err("%s payload length 0x%X exceeds limit",
3715 __func__, event_data->payload_len);
3716 ret = -EINVAL;
3717 goto done;
3718 }
3719
Xiaojun Sangae3d8862018-03-23 08:57:33 +08003720 if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
3721 - sizeof(struct msm_adsp_event_data)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303722 pr_err("%s param length=%d exceeds limit",
3723 __func__, event_data->payload_len);
3724 ret = -EINVAL;
3725 goto done;
3726 }
3727
3728 ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
3729 if (ret < 0)
3730 pr_err("%s: failed to send stream event cmd, err = %d\n",
3731 __func__, ret);
3732done:
3733 return ret;
3734}
3735
3736static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol,
3737 struct snd_ctl_elem_value *ucontrol)
3738{
3739 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3740 unsigned long fe_id = kcontrol->private_value;
3741 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3742 snd_soc_component_get_drvdata(comp);
3743 struct snd_compr_stream *cstream = NULL;
3744 struct msm_compr_audio *prtd;
3745 int fd;
3746 int ret = 0;
3747
3748 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3749 pr_err("%s Received out of bounds invalid fe_id %lu\n",
3750 __func__, fe_id);
3751 ret = -EINVAL;
3752 goto done;
3753 }
3754
3755 cstream = pdata->cstream[fe_id];
3756 if (cstream == NULL) {
3757 pr_err("%s cstream is null\n", __func__);
3758 ret = -EINVAL;
3759 goto done;
3760 }
3761
3762 prtd = cstream->runtime->private_data;
3763 if (!prtd) {
3764 pr_err("%s: prtd is null\n", __func__);
3765 ret = -EINVAL;
3766 goto done;
3767 }
3768
3769 if (prtd->audio_client == NULL) {
3770 pr_err("%s: audio_client is null\n", __func__);
3771 ret = -EINVAL;
3772 goto done;
3773 }
3774
3775 memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd));
3776 ret = q6asm_send_ion_fd(prtd->audio_client, fd);
3777 if (ret < 0)
3778 pr_err("%s: failed to register ion fd\n", __func__);
3779done:
3780 return ret;
3781}
3782
3783static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
3784 struct snd_ctl_elem_value *ucontrol)
3785{
3786 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3787 unsigned long fe_id = kcontrol->private_value;
3788 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3789 snd_soc_component_get_drvdata(comp);
3790 struct snd_compr_stream *cstream = NULL;
3791 struct msm_compr_audio *prtd;
3792 int ret = 0;
3793 int param_length = 0;
3794
3795 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3796 pr_err("%s Received invalid fe_id %lu\n",
3797 __func__, fe_id);
3798 ret = -EINVAL;
3799 goto done;
3800 }
3801
3802 cstream = pdata->cstream[fe_id];
3803 if (cstream == NULL) {
3804 pr_err("%s cstream is null\n", __func__);
3805 ret = -EINVAL;
3806 goto done;
3807 }
3808
3809 prtd = cstream->runtime->private_data;
3810 if (!prtd) {
3811 pr_err("%s: prtd is null\n", __func__);
3812 ret = -EINVAL;
3813 goto done;
3814 }
3815
3816 if (prtd->audio_client == NULL) {
3817 pr_err("%s: audio_client is null\n", __func__);
3818 ret = -EINVAL;
3819 goto done;
3820 }
3821
3822 memcpy(&param_length, ucontrol->value.bytes.data,
3823 sizeof(param_length));
3824 if ((param_length + sizeof(param_length))
3825 >= sizeof(ucontrol->value.bytes.data)) {
3826 pr_err("%s param length=%d exceeds limit",
3827 __func__, param_length);
3828 ret = -EINVAL;
3829 goto done;
3830 }
3831
3832 ret = q6asm_send_rtic_event_ack(prtd->audio_client,
3833 ucontrol->value.bytes.data + sizeof(param_length),
3834 param_length);
3835 if (ret < 0)
3836 pr_err("%s: failed to send rtic event ack, err = %d\n",
3837 __func__, ret);
3838done:
3839 return ret;
3840}
3841
3842static int msm_compr_gapless_put(struct snd_kcontrol *kcontrol,
3843 struct snd_ctl_elem_value *ucontrol)
3844{
3845 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3846 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3847 snd_soc_component_get_drvdata(comp);
3848 pdata->use_dsp_gapless_mode = ucontrol->value.integer.value[0];
3849 pr_debug("%s: value: %ld\n", __func__,
3850 ucontrol->value.integer.value[0]);
3851
3852 return 0;
3853}
3854
3855static int msm_compr_gapless_get(struct snd_kcontrol *kcontrol,
3856 struct snd_ctl_elem_value *ucontrol)
3857{
3858 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3859 struct msm_compr_pdata *pdata =
3860 snd_soc_component_get_drvdata(comp);
3861 pr_debug("%s:gapless mode %d\n", __func__, pdata->use_dsp_gapless_mode);
3862 ucontrol->value.integer.value[0] = pdata->use_dsp_gapless_mode;
3863
3864 return 0;
3865}
3866
3867static const struct snd_kcontrol_new msm_compr_gapless_controls[] = {
3868 SOC_SINGLE_EXT("Compress Gapless Playback",
3869 0, 0, 1, 0,
3870 msm_compr_gapless_get,
3871 msm_compr_gapless_put),
3872};
3873
3874static int msm_compr_probe(struct snd_soc_platform *platform)
3875{
3876 struct msm_compr_pdata *pdata;
3877 int i;
3878 int rc;
3879 const char *qdsp_version;
3880
3881 pr_debug("%s\n", __func__);
3882 pdata = (struct msm_compr_pdata *)
3883 kzalloc(sizeof(*pdata), GFP_KERNEL);
3884 if (!pdata)
3885 return -ENOMEM;
3886
3887 snd_soc_platform_set_drvdata(platform, pdata);
3888
3889 for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) {
3890 pdata->volume[i][0] = COMPRESSED_LR_VOL_MAX_STEPS;
3891 pdata->volume[i][1] = COMPRESSED_LR_VOL_MAX_STEPS;
3892 pdata->audio_effects[i] = NULL;
3893 pdata->dec_params[i] = NULL;
3894 pdata->cstream[i] = NULL;
3895 pdata->ch_map[i] = NULL;
Aditya Bavanari9deef912017-11-20 13:31:31 +05303896 pdata->is_in_use[i] = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303897 }
3898
3899 snd_soc_add_platform_controls(platform, msm_compr_gapless_controls,
3900 ARRAY_SIZE(msm_compr_gapless_controls));
3901
3902 rc = of_property_read_string(platform->dev->of_node,
3903 "qcom,adsp-version", &qdsp_version);
3904 if (!rc) {
3905 if (!strcmp(qdsp_version, "MDSP 1.2"))
3906 pdata->use_legacy_api = true;
3907 else
3908 pdata->use_legacy_api = false;
3909 } else
3910 pdata->use_legacy_api = false;
3911
3912 pr_debug("%s: use legacy api %d\n", __func__, pdata->use_legacy_api);
3913 /*
3914 * use_dsp_gapless_mode part of platform data(pdata) is updated from HAL
3915 * through a mixer control before compress driver is opened. The mixer
3916 * control is used to decide if dsp gapless mode needs to be enabled.
3917 * Gapless is disabled by default.
3918 */
3919 pdata->use_dsp_gapless_mode = false;
3920 return 0;
3921}
3922
Dhanalakshmi Siddani040e0262018-11-26 23:01:26 +05303923static int msm_compr_chmix_cfg_ctl_info(struct snd_kcontrol *kcontrol,
3924 struct snd_ctl_elem_info *uinfo)
3925{
3926 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3927 uinfo->count = 128;
3928 uinfo->value.integer.min = 0;
3929 uinfo->value.integer.max = 0xFFFFFFFF;
3930 return 0;
3931}
3932
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303933static int msm_compr_volume_info(struct snd_kcontrol *kcontrol,
3934 struct snd_ctl_elem_info *uinfo)
3935{
3936 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3937 uinfo->count = 2;
3938 uinfo->value.integer.min = 0;
3939 uinfo->value.integer.max = COMPRESSED_LR_VOL_MAX_STEPS;
3940 return 0;
3941}
3942
3943static int msm_compr_audio_effects_config_info(struct snd_kcontrol *kcontrol,
3944 struct snd_ctl_elem_info *uinfo)
3945{
3946 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3947 uinfo->count = MAX_PP_PARAMS_SZ;
3948 uinfo->value.integer.min = 0;
3949 uinfo->value.integer.max = 0xFFFFFFFF;
3950 return 0;
3951}
3952
3953static int msm_compr_query_audio_effect_info(struct snd_kcontrol *kcontrol,
3954 struct snd_ctl_elem_info *uinfo)
3955{
3956 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3957 uinfo->count = 128;
3958 uinfo->value.integer.min = 0;
3959 uinfo->value.integer.max = 0xFFFFFFFF;
3960 return 0;
3961}
3962
3963static int msm_compr_dec_params_info(struct snd_kcontrol *kcontrol,
3964 struct snd_ctl_elem_info *uinfo)
3965{
3966 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3967 uinfo->count = 128;
3968 uinfo->value.integer.min = 0;
3969 uinfo->value.integer.max = 0xFFFFFFFF;
3970 return 0;
3971}
3972
3973static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol,
3974 struct snd_ctl_elem_info *uinfo)
3975{
3976 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3977 uinfo->count = 5;
3978 uinfo->value.integer.min = 0;
3979 uinfo->value.integer.max = 0xFFFFFFFF;
3980 return 0;
3981}
3982
3983static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol,
3984 struct snd_ctl_elem_info *uinfo)
3985{
3986 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
Dieter Lueckingba7644d2018-09-28 15:09:32 +02003987 uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303988 uinfo->value.integer.min = 0;
Dieter Lueckingba7644d2018-09-28 15:09:32 +02003989 /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */
3990 uinfo->value.integer.max = 34;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303991 return 0;
3992}
3993
3994static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd)
3995{
3996 const char *mixer_ctl_name = "Compress Playback";
3997 const char *deviceNo = "NN";
3998 const char *suffix = "Volume";
3999 char *mixer_str = NULL;
4000 int ctl_len;
4001 struct snd_kcontrol_new fe_volume_control[1] = {
4002 {
4003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4004 .name = "?",
4005 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
4006 SNDRV_CTL_ELEM_ACCESS_READWRITE,
4007 .info = msm_compr_volume_info,
4008 .tlv.p = msm_compr_vol_gain,
4009 .get = msm_compr_volume_get,
4010 .put = msm_compr_volume_put,
4011 .private_value = 0,
4012 }
4013 };
4014
4015 if (!rtd) {
4016 pr_err("%s NULL rtd\n", __func__);
4017 return 0;
4018 }
4019 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4020 __func__, rtd->dai_link->name, rtd->dai_link->id,
4021 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4022 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
4023 strlen(suffix) + 1;
4024 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4025 if (!mixer_str) {
4026 pr_err("failed to allocate mixer ctrl str of len %d", ctl_len);
4027 return 0;
4028 }
4029 snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
4030 rtd->pcm->device, suffix);
4031 fe_volume_control[0].name = mixer_str;
4032 fe_volume_control[0].private_value = rtd->dai_link->id;
4033 pr_debug("Registering new mixer ctl %s", mixer_str);
4034 snd_soc_add_platform_controls(rtd->platform, fe_volume_control,
4035 ARRAY_SIZE(fe_volume_control));
4036 kfree(mixer_str);
4037 return 0;
4038}
4039
4040static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd)
4041{
4042 const char *mixer_ctl_name = "Audio Effects Config";
4043 const char *deviceNo = "NN";
4044 char *mixer_str = NULL;
4045 int ctl_len;
4046 struct snd_kcontrol_new fe_audio_effects_config_control[1] = {
4047 {
4048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4049 .name = "?",
4050 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4051 .info = msm_compr_audio_effects_config_info,
4052 .get = msm_compr_audio_effects_config_get,
4053 .put = msm_compr_audio_effects_config_put,
4054 .private_value = 0,
4055 }
4056 };
4057
4058
4059 if (!rtd) {
4060 pr_err("%s NULL rtd\n", __func__);
4061 return 0;
4062 }
4063
4064 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4065 __func__, rtd->dai_link->name, rtd->dai_link->id,
4066 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4067
4068 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4069 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4070
4071 if (!mixer_str)
4072 return 0;
4073
4074 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4075
4076 fe_audio_effects_config_control[0].name = mixer_str;
4077 fe_audio_effects_config_control[0].private_value = rtd->dai_link->id;
4078 pr_debug("Registering new mixer ctl %s\n", mixer_str);
4079 snd_soc_add_platform_controls(rtd->platform,
4080 fe_audio_effects_config_control,
4081 ARRAY_SIZE(fe_audio_effects_config_control));
4082 kfree(mixer_str);
4083 return 0;
4084}
4085
4086static int msm_compr_add_query_audio_effect_control(
4087 struct snd_soc_pcm_runtime *rtd)
4088{
4089 const char *mixer_ctl_name = "Query Audio Effect Param";
4090 const char *deviceNo = "NN";
4091 char *mixer_str = NULL;
4092 int ctl_len;
4093 struct snd_kcontrol_new fe_query_audio_effect_control[1] = {
4094 {
4095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4096 .name = "?",
4097 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4098 .info = msm_compr_query_audio_effect_info,
4099 .get = msm_compr_query_audio_effect_get,
4100 .put = msm_compr_query_audio_effect_put,
4101 .private_value = 0,
4102 }
4103 };
4104 if (!rtd) {
4105 pr_err("%s NULL rtd\n", __func__);
4106 return 0;
4107 }
4108 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4109 __func__, rtd->dai_link->name, rtd->dai_link->id,
4110 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4111 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4112 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4113 if (!mixer_str) {
4114 pr_err("failed to allocate mixer ctrl str of len %d", ctl_len);
4115 return 0;
4116 }
4117 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4118 fe_query_audio_effect_control[0].name = mixer_str;
4119 fe_query_audio_effect_control[0].private_value = rtd->dai_link->id;
4120 pr_debug("%s: registering new mixer ctl %s\n", __func__, mixer_str);
4121 snd_soc_add_platform_controls(rtd->platform,
4122 fe_query_audio_effect_control,
4123 ARRAY_SIZE(fe_query_audio_effect_control));
4124 kfree(mixer_str);
4125 return 0;
4126}
4127
4128static int msm_compr_add_audio_adsp_stream_cmd_control(
4129 struct snd_soc_pcm_runtime *rtd)
4130{
4131 const char *mixer_ctl_name = DSP_STREAM_CMD;
4132 const char *deviceNo = "NN";
4133 char *mixer_str = NULL;
4134 int ctl_len = 0, ret = 0;
4135 struct snd_kcontrol_new fe_audio_adsp_stream_cmd_config_control[1] = {
4136 {
4137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4138 .name = "?",
4139 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4140 .info = msm_adsp_stream_cmd_info,
4141 .put = msm_compr_adsp_stream_cmd_put,
4142 .private_value = 0,
4143 }
4144 };
4145
4146 if (!rtd) {
4147 pr_err("%s NULL rtd\n", __func__);
4148 ret = -EINVAL;
4149 goto done;
4150 }
4151
4152 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4153 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4154 if (!mixer_str) {
4155 ret = -ENOMEM;
4156 goto done;
4157 }
4158
4159 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4160 fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str;
4161 fe_audio_adsp_stream_cmd_config_control[0].private_value =
4162 rtd->dai_link->id;
4163 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4164 ret = snd_soc_add_platform_controls(rtd->platform,
4165 fe_audio_adsp_stream_cmd_config_control,
4166 ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control));
4167 if (ret < 0)
4168 pr_err("%s: failed to add ctl %s. err = %d\n",
4169 __func__, mixer_str, ret);
4170
4171 kfree(mixer_str);
4172done:
4173 return ret;
4174}
4175
4176static int msm_compr_add_audio_adsp_stream_callback_control(
4177 struct snd_soc_pcm_runtime *rtd)
4178{
4179 const char *mixer_ctl_name = DSP_STREAM_CALLBACK;
4180 const char *deviceNo = "NN";
4181 char *mixer_str = NULL;
4182 int ctl_len = 0, ret = 0;
4183 struct snd_kcontrol *kctl;
4184
4185 struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = {
4186 {
4187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4188 .name = "?",
4189 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4190 .info = msm_adsp_stream_callback_info,
4191 .get = msm_adsp_stream_callback_get,
4192 .private_value = 0,
4193 }
4194 };
4195
4196 if (!rtd) {
4197 pr_err("%s: rtd is NULL\n", __func__);
4198 ret = -EINVAL;
4199 goto done;
4200 }
4201
4202 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4203 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4204 if (!mixer_str) {
4205 ret = -ENOMEM;
4206 goto done;
4207 }
4208
4209 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4210 fe_audio_adsp_callback_config_control[0].name = mixer_str;
4211 fe_audio_adsp_callback_config_control[0].private_value =
4212 rtd->dai_link->id;
4213 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4214 ret = snd_soc_add_platform_controls(rtd->platform,
4215 fe_audio_adsp_callback_config_control,
4216 ARRAY_SIZE(fe_audio_adsp_callback_config_control));
4217 if (ret < 0) {
4218 pr_err("%s: failed to add ctl %s. err = %d\n",
4219 __func__, mixer_str, ret);
4220 ret = -EINVAL;
4221 goto free_mixer_str;
4222 }
4223
4224 kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
4225 if (!kctl) {
4226 pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
4227 ret = -EINVAL;
4228 goto free_mixer_str;
4229 }
4230
4231 kctl->private_data = NULL;
4232
4233free_mixer_str:
4234 kfree(mixer_str);
4235done:
4236 return ret;
4237}
4238
4239static int msm_compr_add_dec_runtime_params_control(
4240 struct snd_soc_pcm_runtime *rtd)
4241{
4242 const char *mixer_ctl_name = "Audio Stream";
4243 const char *deviceNo = "NN";
4244 const char *suffix = "Dec Params";
4245 char *mixer_str = NULL;
4246 int ctl_len;
4247 struct snd_kcontrol_new fe_dec_params_control[1] = {
4248 {
4249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4250 .name = "?",
4251 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4252 .info = msm_compr_dec_params_info,
4253 .get = msm_compr_dec_params_get,
4254 .put = msm_compr_dec_params_put,
4255 .private_value = 0,
4256 }
4257 };
4258
4259 if (!rtd) {
4260 pr_err("%s NULL rtd\n", __func__);
4261 return 0;
4262 }
4263
4264 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4265 __func__, rtd->dai_link->name, rtd->dai_link->id,
4266 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4267
4268 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
4269 strlen(suffix) + 1;
4270 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4271
4272 if (!mixer_str)
4273 return 0;
4274
4275 snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
4276 rtd->pcm->device, suffix);
4277
4278 fe_dec_params_control[0].name = mixer_str;
4279 fe_dec_params_control[0].private_value = rtd->dai_link->id;
4280 pr_debug("Registering new mixer ctl %s", mixer_str);
4281 snd_soc_add_platform_controls(rtd->platform,
4282 fe_dec_params_control,
4283 ARRAY_SIZE(fe_dec_params_control));
4284 kfree(mixer_str);
4285 return 0;
4286}
4287
4288static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd)
4289{
4290 const char *playback_mixer_ctl_name = "Audio Stream";
4291 const char *capture_mixer_ctl_name = "Audio Stream Capture";
4292 const char *deviceNo = "NN";
4293 const char *suffix = "App Type Cfg";
4294 char *mixer_str = NULL;
4295 int ctl_len;
4296 struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
4297 {
4298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4299 .name = "?",
4300 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4301 .info = msm_compr_app_type_cfg_info,
4302 .put = msm_compr_playback_app_type_cfg_put,
4303 .get = msm_compr_playback_app_type_cfg_get,
4304 .private_value = 0,
4305 }
4306 };
4307
4308 if (!rtd) {
4309 pr_err("%s NULL rtd\n", __func__);
4310 return 0;
4311 }
4312
4313 pr_debug("%s: added new compr FE ctl with name %s, id %d, cpu dai %s, device no %d\n",
4314 __func__, rtd->dai_link->name, rtd->dai_link->id,
4315 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4316 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK)
4317 ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo)
4318 + 1 + strlen(suffix) + 1;
4319 else
4320 ctl_len = strlen(capture_mixer_ctl_name) + 1 + strlen(deviceNo)
4321 + 1 + strlen(suffix) + 1;
4322
4323 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4324
4325 if (!mixer_str)
4326 return 0;
4327
4328 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK)
4329 snprintf(mixer_str, ctl_len, "%s %d %s",
4330 playback_mixer_ctl_name, rtd->pcm->device, suffix);
4331 else
4332 snprintf(mixer_str, ctl_len, "%s %d %s",
4333 capture_mixer_ctl_name, rtd->pcm->device, suffix);
4334
4335 fe_app_type_cfg_control[0].name = mixer_str;
4336 fe_app_type_cfg_control[0].private_value = rtd->dai_link->id;
4337
4338 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) {
4339 fe_app_type_cfg_control[0].put =
4340 msm_compr_playback_app_type_cfg_put;
4341 fe_app_type_cfg_control[0].get =
4342 msm_compr_playback_app_type_cfg_get;
4343 } else {
4344 fe_app_type_cfg_control[0].put =
4345 msm_compr_capture_app_type_cfg_put;
4346 fe_app_type_cfg_control[0].get =
4347 msm_compr_capture_app_type_cfg_get;
4348 }
4349 pr_debug("Registering new mixer ctl %s", mixer_str);
4350 snd_soc_add_platform_controls(rtd->platform,
4351 fe_app_type_cfg_control,
4352 ARRAY_SIZE(fe_app_type_cfg_control));
4353 kfree(mixer_str);
4354 return 0;
4355}
4356
Dhanalakshmi Siddani040e0262018-11-26 23:01:26 +05304357static int msm_compr_chmix_cfg_ctl_put(struct snd_kcontrol *kcontrol,
4358 struct snd_ctl_elem_value *ucontrol)
4359{
4360 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
4361 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
4362 snd_soc_component_get_drvdata(comp);
4363 struct snd_compr_stream *cstream = NULL;
4364 struct snd_soc_pcm_runtime *rtd = NULL;
4365 u64 fe_id = kcontrol->private_value;
4366 int ip_channel_cnt, op_channel_cnt;
4367 int i, index = 0;
4368 int ch_coeff[PCM_FORMAT_MAX_NUM_CHANNEL * PCM_FORMAT_MAX_NUM_CHANNEL];
4369 bool use_default_chmap = true;
4370 char *chmap = NULL;
4371
4372 pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
4373 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
4374 pr_err("%s: Received out of bounds fe_id %llu\n",
4375 __func__, fe_id);
4376 return -EINVAL;
4377 }
4378 cstream = pdata->cstream[fe_id];
4379 if (!cstream) {
4380 pr_err("%s: stream inactive\n", __func__);
4381 return -EINVAL;
4382 }
4383 rtd = cstream->private_data;
4384 if (!rtd) {
4385 pr_err("%s: stream inactive\n", __func__);
4386 return -EINVAL;
4387 }
4388
4389 use_default_chmap = !(pdata->ch_map[rtd->dai_link->id]->set_ch_map);
4390 chmap = pdata->ch_map[rtd->dai_link->id]->channel_map;
4391
4392 ip_channel_cnt = ucontrol->value.integer.value[index++];
4393 op_channel_cnt = ucontrol->value.integer.value[index++];
4394 /*
4395 * wght coeff of first out channel corresponding to each in channel
4396 * are sent followed by second out channel for each in channel etc.
4397 */
4398 memset(ch_coeff, 0, sizeof(ch_coeff));
4399 for (i = 0; i < op_channel_cnt * ip_channel_cnt; i++) {
4400 ch_coeff[i] =
4401 ucontrol->value.integer.value[index++];
4402 }
4403
4404 msm_pcm_routing_send_chmix_cfg(fe_id, ip_channel_cnt, op_channel_cnt,
4405 ch_coeff, SESSION_TYPE_RX, use_default_chmap, chmap);
4406
4407 return 0;
4408}
4409
4410static int msm_compr_chmix_cfg_ctl_get(struct snd_kcontrol *kcontrol,
4411 struct snd_ctl_elem_value *ucontrol)
4412{
4413 return 0;
4414}
4415
4416static int msm_compr_add_chmix_cfg_controls(struct snd_soc_pcm_runtime *rtd)
4417{
4418 const char *mixer_ctl_name = "Audio Stream";
4419 const char *deviceNo = "NN";
4420 const char *suffix = "Channel Mix Cfg";
4421 int ctl_len;
4422 char *mixer_str = NULL;
4423 struct snd_kcontrol_new chmix_cfg_controls[1] = {
4424 {
4425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4426 .name = "?",
4427 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4428 .info = msm_compr_chmix_cfg_ctl_info,
4429 .get = msm_compr_chmix_cfg_ctl_get,
4430 .put = msm_compr_chmix_cfg_ctl_put,
4431 .private_value = 0,
4432 }
4433 };
4434
4435 if (!rtd) {
4436 pr_err("%s NULL rtd\n", __func__);
4437 return -EINVAL;
4438 }
4439
4440 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4441 __func__, rtd->dai_link->name, rtd->dai_link->id,
4442 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4443
4444 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
4445 strlen(suffix) + 1;
4446 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4447 if (!mixer_str)
4448 return -ENOMEM;
4449
4450 snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
4451 rtd->pcm->device, suffix);
4452
4453 chmix_cfg_controls[0].name = mixer_str;
4454 chmix_cfg_controls[0].private_value = rtd->dai_link->id;
4455 pr_debug("%s: Registering new mixer ctl %s", __func__, mixer_str);
4456 snd_soc_add_platform_controls(rtd->platform,
4457 chmix_cfg_controls,
4458 ARRAY_SIZE(chmix_cfg_controls));
4459 kfree(mixer_str);
4460 return 0;
4461}
4462
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304463static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd)
4464{
4465 const char *mixer_ctl_name = "Playback Channel Map";
4466 const char *deviceNo = "NN";
4467 char *mixer_str = NULL;
4468 struct msm_compr_pdata *pdata = NULL;
4469 int ctl_len;
4470 struct snd_kcontrol_new fe_channel_map_control[1] = {
4471 {
4472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4473 .name = "?",
4474 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4475 .info = msm_compr_channel_map_info,
4476 .get = msm_compr_channel_map_get,
4477 .put = msm_compr_channel_map_put,
4478 .private_value = 0,
4479 }
4480 };
4481
4482 if (!rtd) {
4483 pr_err("%s: NULL rtd\n", __func__);
4484 return -EINVAL;
4485 }
4486
4487 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4488 __func__, rtd->dai_link->name, rtd->dai_link->id,
4489 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4490
4491 ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1;
4492 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4493
4494 if (!mixer_str)
4495 return -ENOMEM;
4496
4497 snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device);
4498
4499 fe_channel_map_control[0].name = mixer_str;
4500 fe_channel_map_control[0].private_value = rtd->dai_link->id;
4501 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4502 snd_soc_add_platform_controls(rtd->platform,
4503 fe_channel_map_control,
4504 ARRAY_SIZE(fe_channel_map_control));
4505
4506 pdata = snd_soc_platform_get_drvdata(rtd->platform);
4507 pdata->ch_map[rtd->dai_link->id] =
4508 kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL);
4509 if (!pdata->ch_map[rtd->dai_link->id]) {
4510 pr_err("%s: Could not allocate memory for channel map\n",
4511 __func__);
4512 kfree(mixer_str);
4513 return -ENOMEM;
4514 }
4515 kfree(mixer_str);
4516 return 0;
4517}
4518
4519static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd)
4520{
4521 const char *mixer_ctl_name = "Playback ION FD";
4522 const char *deviceNo = "NN";
4523 char *mixer_str = NULL;
4524 int ctl_len = 0, ret = 0;
4525 struct snd_kcontrol_new fe_ion_fd_config_control[1] = {
4526 {
4527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4528 .name = "?",
4529 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4530 .info = msm_adsp_stream_cmd_info,
4531 .put = msm_compr_ion_fd_map_put,
4532 .private_value = 0,
4533 }
4534 };
4535
4536 if (!rtd) {
4537 pr_err("%s NULL rtd\n", __func__);
4538 ret = -EINVAL;
4539 goto done;
4540 }
4541
4542 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4543 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4544 if (!mixer_str) {
4545 ret = -ENOMEM;
4546 goto done;
4547 }
4548
4549 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4550 fe_ion_fd_config_control[0].name = mixer_str;
4551 fe_ion_fd_config_control[0].private_value = rtd->dai_link->id;
4552 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4553 ret = snd_soc_add_platform_controls(rtd->platform,
4554 fe_ion_fd_config_control,
4555 ARRAY_SIZE(fe_ion_fd_config_control));
4556 if (ret < 0)
4557 pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
4558
4559 kfree(mixer_str);
4560done:
4561 return ret;
4562}
4563
4564static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd)
4565{
4566 const char *mixer_ctl_name = "Playback Event Ack";
4567 const char *deviceNo = "NN";
4568 char *mixer_str = NULL;
4569 int ctl_len = 0, ret = 0;
4570 struct snd_kcontrol_new fe_event_ack_config_control[1] = {
4571 {
4572 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4573 .name = "?",
4574 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4575 .info = msm_adsp_stream_cmd_info,
4576 .put = msm_compr_rtic_event_ack_put,
4577 .private_value = 0,
4578 }
4579 };
4580
4581 if (!rtd) {
4582 pr_err("%s NULL rtd\n", __func__);
4583 ret = -EINVAL;
4584 goto done;
4585 }
4586
4587 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4588 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4589 if (!mixer_str) {
4590 ret = -ENOMEM;
4591 goto done;
4592 }
4593
4594 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4595 fe_event_ack_config_control[0].name = mixer_str;
4596 fe_event_ack_config_control[0].private_value = rtd->dai_link->id;
4597 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4598 ret = snd_soc_add_platform_controls(rtd->platform,
4599 fe_event_ack_config_control,
4600 ARRAY_SIZE(fe_event_ack_config_control));
4601 if (ret < 0)
4602 pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
4603
4604 kfree(mixer_str);
4605done:
4606 return ret;
4607}
4608
4609static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
4610{
4611 int rc;
4612
4613 rc = msm_compr_add_volume_control(rtd);
4614 if (rc)
4615 pr_err("%s: Could not add Compr Volume Control\n", __func__);
4616
4617 rc = msm_compr_add_audio_effects_control(rtd);
4618 if (rc)
4619 pr_err("%s: Could not add Compr Audio Effects Control\n",
4620 __func__);
4621
4622 rc = msm_compr_add_audio_adsp_stream_cmd_control(rtd);
4623 if (rc)
4624 pr_err("%s: Could not add Compr ADSP Stream Cmd Control\n",
4625 __func__);
4626
4627 rc = msm_compr_add_audio_adsp_stream_callback_control(rtd);
4628 if (rc)
4629 pr_err("%s: Could not add Compr ADSP Stream Callback Control\n",
4630 __func__);
4631
4632 rc = msm_compr_add_io_fd_cmd_control(rtd);
4633 if (rc)
4634 pr_err("%s: Could not add Compr ion fd Control\n",
4635 __func__);
4636
4637 rc = msm_compr_add_event_ack_cmd_control(rtd);
4638 if (rc)
4639 pr_err("%s: Could not add Compr event ack Control\n",
4640 __func__);
4641
4642 rc = msm_compr_add_query_audio_effect_control(rtd);
4643 if (rc)
4644 pr_err("%s: Could not add Compr Query Audio Effect Control\n",
4645 __func__);
4646
4647 rc = msm_compr_add_dec_runtime_params_control(rtd);
4648 if (rc)
4649 pr_err("%s: Could not add Compr Dec runtime params Control\n",
4650 __func__);
4651 rc = msm_compr_add_app_type_cfg_control(rtd);
4652 if (rc)
4653 pr_err("%s: Could not add Compr App Type Cfg Control\n",
4654 __func__);
4655 rc = msm_compr_add_channel_map_control(rtd);
4656 if (rc)
4657 pr_err("%s: Could not add Compr Channel Map Control\n",
4658 __func__);
Dhanalakshmi Siddani040e0262018-11-26 23:01:26 +05304659 rc = msm_compr_add_chmix_cfg_controls(rtd);
4660 if (rc)
4661 pr_err("%s: add chmix cfg controls failed:%d\n", __func__, rc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304662 return 0;
4663}
4664
4665static struct snd_compr_ops msm_compr_ops = {
4666 .open = msm_compr_open,
4667 .free = msm_compr_free,
4668 .trigger = msm_compr_trigger,
4669 .pointer = msm_compr_pointer,
4670 .set_params = msm_compr_set_params,
4671 .set_metadata = msm_compr_set_metadata,
4672 .get_metadata = msm_compr_get_metadata,
4673 .set_next_track_param = msm_compr_set_next_track_param,
4674 .ack = msm_compr_ack,
4675 .copy = msm_compr_copy,
4676 .get_caps = msm_compr_get_caps,
4677 .get_codec_caps = msm_compr_get_codec_caps,
4678};
4679
4680static struct snd_soc_platform_driver msm_soc_platform = {
4681 .probe = msm_compr_probe,
4682 .compr_ops = &msm_compr_ops,
4683 .pcm_new = msm_compr_new,
4684};
4685
4686static int msm_compr_dev_probe(struct platform_device *pdev)
4687{
4688
4689 pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
4690 return snd_soc_register_platform(&pdev->dev,
4691 &msm_soc_platform);
4692}
4693
4694static int msm_compr_remove(struct platform_device *pdev)
4695{
4696 snd_soc_unregister_platform(&pdev->dev);
4697 return 0;
4698}
4699
4700static const struct of_device_id msm_compr_dt_match[] = {
4701 {.compatible = "qcom,msm-compress-dsp"},
4702 {}
4703};
4704MODULE_DEVICE_TABLE(of, msm_compr_dt_match);
4705
4706static struct platform_driver msm_compr_driver = {
4707 .driver = {
4708 .name = "msm-compress-dsp",
4709 .owner = THIS_MODULE,
4710 .of_match_table = msm_compr_dt_match,
4711 },
4712 .probe = msm_compr_dev_probe,
4713 .remove = msm_compr_remove,
4714};
4715
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304716int __init msm_compress_dsp_init(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304717{
4718 return platform_driver_register(&msm_compr_driver);
4719}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304720
Asish Bhattacharya5faacb32017-12-04 17:23:15 +05304721void msm_compress_dsp_exit(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304722{
4723 platform_driver_unregister(&msm_compr_driver);
4724}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304725
4726MODULE_DESCRIPTION("Compress Offload platform driver");
4727MODULE_LICENSE("GPL v2");