blob: d35ed890d66fe09e534912f7e73802d4d4b0c9ce [file] [log] [blame]
Sachin Mohan Gadag7c944232018-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 Lueckingceef9af2018-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 Lueckingceef9af2018-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 }
Ralf Herz22573552018-06-20 11:30:58 +0200544 prtd->bytes_read += buffer_length + prtd->ts_header_offset;
Vikram Panduranga82c2c2c2018-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;
Ralf Herz22573552018-06-20 11:30:58 +0200680 /* Write the actual length of the received buffer */
681 *buff_addr = payload[4];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530682 buff_addr++;
683 /* Write the offset */
684 *buff_addr = prtd->ts_header_offset;
685 buff_addr++;
686 /* Write the TS LSW */
687 *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_LSW];
688 buff_addr++;
689 /* Write the TS MSW */
690 *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_MSW];
691 }
692 /* Always assume read_size is same as fragment_size */
693 read_size = prtd->codec_param.buffer.fragment_size;
694 prtd->byte_offset += read_size;
695 prtd->received_total += read_size;
696 if (prtd->byte_offset >= prtd->buffer_size)
697 prtd->byte_offset -= prtd->buffer_size;
698
699 snd_compr_fragment_elapsed(cstream);
700
701 if (!atomic_read(&prtd->start)) {
702 pr_debug("read_done received while not started, treat as xrun");
703 atomic_set(&prtd->xrun, 1);
704 spin_unlock_irqrestore(&prtd->lock, flags);
705 break;
706 }
707 msm_compr_read_buffer(prtd);
708
709 spin_unlock_irqrestore(&prtd->lock, flags);
710 break;
711
712 case ASM_DATA_EVENT_RENDERED_EOS:
713 spin_lock_irqsave(&prtd->lock, flags);
714 pr_debug("%s: ASM_DATA_CMDRSP_EOS token 0x%x,stream id %d\n",
715 __func__, token, stream_id);
716 if (atomic_read(&prtd->eos) &&
717 !prtd->gapless_state.set_next_stream_id) {
718 pr_debug("ASM_DATA_CMDRSP_EOS wake up\n");
719 prtd->eos_ack = 1;
720 wake_up(&prtd->eos_wait);
721 }
722 atomic_set(&prtd->eos, 0);
723 stream_index = STREAM_ARRAY_INDEX(stream_id);
724 if (stream_index >= MAX_NUMBER_OF_STREAMS ||
725 stream_index < 0) {
726 pr_err("%s: Invalid stream index %d", __func__,
727 stream_index);
728 spin_unlock_irqrestore(&prtd->lock, flags);
729 break;
730 }
731
732 if (prtd->gapless_state.set_next_stream_id &&
733 prtd->gapless_state.stream_opened[stream_index]) {
734 pr_debug("%s: CMD_CLOSE stream_id %d\n",
735 __func__, stream_id);
736 q6asm_stream_cmd_nowait(ac, CMD_CLOSE, stream_id);
737 atomic_set(&prtd->close, 1);
738 prtd->gapless_state.stream_opened[stream_index] = 0;
739 prtd->gapless_state.set_next_stream_id = false;
740 }
741 if (prtd->gapless_state.gapless_transition)
742 prtd->gapless_state.gapless_transition = 0;
743 spin_unlock_irqrestore(&prtd->lock, flags);
744 break;
745 case ASM_STREAM_PP_EVENT:
746 case ASM_STREAM_CMD_ENCDEC_EVENTS:
747 pr_debug("%s: ASM_STREAM_EVENT(0x%x)\n", __func__, opcode);
748 rtd = cstream->private_data;
749 if (!rtd) {
750 pr_err("%s: rtd is NULL\n", __func__);
751 return;
752 }
753
754 ret = msm_adsp_inform_mixer_ctl(rtd, payload);
755 if (ret) {
756 pr_err("%s: failed to inform mixer ctrl. err = %d\n",
757 __func__, ret);
758 return;
759 }
760 break;
761 case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
762 case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: {
763 pr_debug("ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY\n");
764 chan_mode = payload[1] >> 16;
765 sample_rate = payload[2] >> 16;
766 if (prtd && (chan_mode != prtd->num_channels ||
767 sample_rate != prtd->sample_rate)) {
768 prtd->num_channels = chan_mode;
769 prtd->sample_rate = sample_rate;
770 }
771 }
772 /* Fallthrough here */
773 case APR_BASIC_RSP_RESULT: {
774 switch (payload[0]) {
775 case ASM_SESSION_CMD_RUN_V2:
776 /* check if the first buffer need to be sent to DSP */
777 pr_debug("ASM_SESSION_CMD_RUN_V2\n");
778
779 /* FIXME: A state is a better way, dealing with this */
780 spin_lock_irqsave(&prtd->lock, flags);
781
782 if (cstream->direction == SND_COMPRESS_CAPTURE) {
783 atomic_set(&prtd->start, 1);
784 msm_compr_read_buffer(prtd);
785 spin_unlock_irqrestore(&prtd->lock, flags);
786 break;
787 }
788
789 if (!prtd->bytes_sent) {
790 bytes_available = prtd->bytes_received -
791 prtd->copied_total;
792 if (bytes_available <
793 cstream->runtime->fragment_size) {
794 pr_debug("CMD_RUN_V2 Insufficient data to send. break out\n");
795 atomic_set(&prtd->xrun, 1);
796 } else {
797 msm_compr_send_buffer(prtd);
798 }
799 }
800
801 /*
802 * The condition below ensures playback finishes in the
803 * follow cornercase
804 * WRITE(last buffer)
805 * WAIT_FOR_DRAIN
806 * PAUSE
807 * WRITE_DONE(X)
808 * RESUME
809 */
810 if ((prtd->copied_total == prtd->bytes_sent) &&
811 atomic_read(&prtd->drain)) {
812 pr_debug("RUN ack, wake up & continue pending drain\n");
813
814 if (prtd->last_buffer)
815 prtd->last_buffer = 0;
816
817 prtd->drain_ready = 1;
818 wake_up(&prtd->drain_wait);
819 atomic_set(&prtd->drain, 0);
820 }
821
822 spin_unlock_irqrestore(&prtd->lock, flags);
823 break;
824 case ASM_STREAM_CMD_FLUSH:
825 pr_debug("%s: ASM_STREAM_CMD_FLUSH:", __func__);
826 pr_debug("token 0x%x, stream id %d\n", token,
827 stream_id);
828 prtd->cmd_ack = 1;
829 break;
830 case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
831 pr_debug("%s: ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:",
832 __func__);
833 pr_debug("token 0x%x, stream id = %d\n", token,
834 stream_id);
835 break;
836 case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
837 pr_debug("%s: ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:",
838 __func__);
839 pr_debug("token = 0x%x, stream id = %d\n", token,
840 stream_id);
841 break;
842 case ASM_STREAM_CMD_CLOSE:
843 pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__);
844 pr_debug("token 0x%x, stream id %d\n", token,
845 stream_id);
846 /*
847 * wakeup wait for stream avail on stream 3
848 * after stream 1 ends.
849 */
850 if (prtd->next_stream) {
851 pr_debug("%s:CLOSE:wakeup wait for stream\n",
852 __func__);
853 prtd->stream_available = 1;
854 wake_up(&prtd->wait_for_stream_avail);
855 prtd->next_stream = 0;
856 }
857 if (atomic_read(&prtd->close) &&
858 atomic_read(&prtd->wait_on_close)) {
859 prtd->cmd_ack = 1;
860 wake_up(&prtd->close_wait);
861 }
862 atomic_set(&prtd->close, 0);
863 break;
864 case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
865 pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:",
866 __func__);
867 break;
868 default:
869 break;
870 }
871 break;
872 }
873 case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
874 pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3\n",
875 __func__);
876 break;
877 case RESET_EVENTS:
878 pr_err("%s: Received reset events CB, move to error state",
879 __func__);
880 spin_lock_irqsave(&prtd->lock, flags);
881 /*
882 * Since ADSP is down, let this driver pretend that it copied
883 * all the bytes received, so that next write will be triggered
884 */
885 prtd->copied_total = prtd->bytes_received;
886 snd_compr_fragment_elapsed(cstream);
887 atomic_set(&prtd->error, 1);
888 wake_up(&prtd->drain_wait);
889 if (atomic_cmpxchg(&prtd->eos, 1, 0)) {
890 pr_debug("%s:unblock eos wait queues", __func__);
891 wake_up(&prtd->eos_wait);
892 }
893 spin_unlock_irqrestore(&prtd->lock, flags);
894 break;
895 default:
896 pr_debug("%s: Not Supported Event opcode[0x%x]\n",
897 __func__, opcode);
898 break;
899 }
900}
901
902static int msm_compr_get_partial_drain_delay(int frame_sz, int sample_rate)
903{
904 int delay_time_ms = 0;
905
906 delay_time_ms = ((DSP_NUM_OUTPUT_FRAME_BUFFERED * frame_sz * 1000) /
907 sample_rate) + DSP_PP_BUFFERING_IN_MSEC;
908 delay_time_ms = delay_time_ms > PARTIAL_DRAIN_ACK_EARLY_BY_MSEC ?
909 delay_time_ms - PARTIAL_DRAIN_ACK_EARLY_BY_MSEC : 0;
910
911 pr_debug("%s: frame_sz %d, sample_rate %d, partial drain delay %d\n",
912 __func__, frame_sz, sample_rate, delay_time_ms);
913 return delay_time_ms;
914}
915
916static void populate_codec_list(struct msm_compr_audio *prtd)
917{
918 pr_debug("%s\n", __func__);
919 prtd->compr_cap.direction = SND_COMPRESS_PLAYBACK;
920 prtd->compr_cap.min_fragment_size =
921 COMPR_PLAYBACK_MIN_FRAGMENT_SIZE;
922 prtd->compr_cap.max_fragment_size =
923 COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
924 prtd->compr_cap.min_fragments =
925 COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
926 prtd->compr_cap.max_fragments =
927 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
928 prtd->compr_cap.num_codecs = 17;
929 prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
930 prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
931 prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
932 prtd->compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3;
933 prtd->compr_cap.codecs[4] = SND_AUDIOCODEC_MP2;
934 prtd->compr_cap.codecs[5] = SND_AUDIOCODEC_PCM;
935 prtd->compr_cap.codecs[6] = SND_AUDIOCODEC_WMA;
936 prtd->compr_cap.codecs[7] = SND_AUDIOCODEC_WMA_PRO;
937 prtd->compr_cap.codecs[8] = SND_AUDIOCODEC_FLAC;
938 prtd->compr_cap.codecs[9] = SND_AUDIOCODEC_VORBIS;
939 prtd->compr_cap.codecs[10] = SND_AUDIOCODEC_ALAC;
940 prtd->compr_cap.codecs[11] = SND_AUDIOCODEC_APE;
941 prtd->compr_cap.codecs[12] = SND_AUDIOCODEC_DTS;
942 prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD;
943 prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX;
944 prtd->compr_cap.codecs[15] = SND_AUDIOCODEC_TRUEHD;
945 prtd->compr_cap.codecs[16] = SND_AUDIOCODEC_IEC61937;
946}
947
948static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
949 int stream_id,
950 bool use_gapless_codec_options)
951{
952 struct snd_compr_runtime *runtime = cstream->runtime;
953 struct msm_compr_audio *prtd = runtime->private_data;
954 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
955 struct msm_compr_pdata *pdata =
956 snd_soc_platform_get_drvdata(rtd->platform);
957 struct asm_aac_cfg aac_cfg;
958 struct asm_wma_cfg wma_cfg;
959 struct asm_wmapro_cfg wma_pro_cfg;
960 struct asm_flac_cfg flac_cfg;
961 struct asm_vorbis_cfg vorbis_cfg;
962 struct asm_alac_cfg alac_cfg;
963 struct asm_ape_cfg ape_cfg;
964 struct asm_dsd_cfg dsd_cfg;
965 struct aptx_dec_bt_addr_cfg aptx_cfg;
966 union snd_codec_options *codec_options;
967
968 int ret = 0;
969 uint16_t bit_width;
970 bool use_default_chmap = true;
971 char *chmap = NULL;
972 uint16_t sample_word_size;
973
974 pr_debug("%s: use_gapless_codec_options %d\n",
975 __func__, use_gapless_codec_options);
976
977 if (use_gapless_codec_options)
978 codec_options = &(prtd->gapless_state.codec_options);
979 else
980 codec_options = &(prtd->codec_param.codec.options);
981
982 if (!codec_options) {
983 pr_err("%s: codec_options is NULL\n", __func__);
984 return -EINVAL;
985 }
986
987 switch (prtd->codec) {
988 case FORMAT_LINEAR_PCM:
989 pr_debug("SND_AUDIOCODEC_PCM\n");
990 if (pdata->ch_map[rtd->dai_link->id]) {
991 use_default_chmap =
992 !(pdata->ch_map[rtd->dai_link->id]->set_ch_map);
993 chmap =
994 pdata->ch_map[rtd->dai_link->id]->channel_map;
995 }
996
997 switch (prtd->codec_param.codec.format) {
998 case SNDRV_PCM_FORMAT_S32_LE:
999 bit_width = 32;
1000 sample_word_size = 32;
1001 break;
1002 case SNDRV_PCM_FORMAT_S24_LE:
1003 bit_width = 24;
1004 sample_word_size = 32;
1005 break;
1006 case SNDRV_PCM_FORMAT_S24_3LE:
1007 bit_width = 24;
1008 sample_word_size = 24;
1009 break;
1010 case SNDRV_PCM_FORMAT_S16_LE:
1011 default:
1012 bit_width = 16;
1013 sample_word_size = 16;
1014 break;
1015 }
Dieter Lueckingceef9af2018-09-28 15:09:32 +02001016
1017 if (q6core_get_avcs_api_version_per_service(
1018 APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
1019 ADSP_ASM_API_VERSION_V2) {
1020 ret = q6asm_media_format_block_pcm_format_support_v5(
1021 prtd->audio_client,
1022 prtd->sample_rate,
1023 prtd->num_channels,
1024 bit_width, stream_id,
1025 use_default_chmap,
1026 chmap,
1027 sample_word_size,
1028 ASM_LITTLE_ENDIAN,
1029 DEFAULT_QF);
1030 } else {
1031 ret = q6asm_media_format_block_pcm_format_support_v4(
1032 prtd->audio_client,
1033 prtd->sample_rate,
1034 prtd->num_channels,
1035 bit_width, stream_id,
1036 use_default_chmap,
1037 chmap,
1038 sample_word_size,
1039 ASM_LITTLE_ENDIAN,
1040 DEFAULT_QF);
1041 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301042 if (ret < 0)
1043 pr_err("%s: CMD Format block failed\n", __func__);
1044
1045 break;
1046 case FORMAT_MP3:
1047 pr_debug("SND_AUDIOCODEC_MP3\n");
1048 /* no media format block needed */
1049 break;
1050 case FORMAT_MPEG4_AAC:
1051 pr_debug("SND_AUDIOCODEC_AAC\n");
1052 memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg));
1053 aac_cfg.aot = AAC_ENC_MODE_EAAC_P;
1054 if (prtd->codec_param.codec.format ==
1055 SND_AUDIOSTREAMFORMAT_MP4ADTS)
1056 aac_cfg.format = 0x0;
1057 else if (prtd->codec_param.codec.format ==
1058 SND_AUDIOSTREAMFORMAT_MP4LATM)
1059 aac_cfg.format = 0x04;
1060 else
1061 aac_cfg.format = 0x03;
1062 aac_cfg.ch_cfg = prtd->num_channels;
1063 aac_cfg.sample_rate = prtd->sample_rate;
1064 ret = q6asm_stream_media_format_block_aac(prtd->audio_client,
1065 &aac_cfg, stream_id);
1066 if (ret < 0)
1067 pr_err("%s: CMD Format block failed\n", __func__);
1068 break;
1069 case FORMAT_AC3:
1070 pr_debug("SND_AUDIOCODEC_AC3\n");
1071 break;
1072 case FORMAT_EAC3:
1073 pr_debug("SND_AUDIOCODEC_EAC3\n");
1074 break;
1075 case FORMAT_WMA_V9:
1076 pr_debug("SND_AUDIOCODEC_WMA\n");
1077 memset(&wma_cfg, 0x0, sizeof(struct asm_wma_cfg));
1078 wma_cfg.format_tag = prtd->codec_param.codec.format;
1079 wma_cfg.ch_cfg = prtd->codec_param.codec.ch_in;
1080 wma_cfg.sample_rate = prtd->sample_rate;
1081 wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8;
1082 wma_cfg.block_align = codec_options->wma.super_block_align;
1083 wma_cfg.valid_bits_per_sample =
1084 codec_options->wma.bits_per_sample;
1085 wma_cfg.ch_mask = codec_options->wma.channelmask;
1086 wma_cfg.encode_opt = codec_options->wma.encodeopt;
1087 ret = q6asm_media_format_block_wma(prtd->audio_client,
1088 &wma_cfg, stream_id);
1089 if (ret < 0)
1090 pr_err("%s: CMD Format block failed\n", __func__);
1091 break;
1092 case FORMAT_WMA_V10PRO:
1093 pr_debug("SND_AUDIOCODEC_WMA_PRO\n");
1094 memset(&wma_pro_cfg, 0x0, sizeof(struct asm_wmapro_cfg));
1095 wma_pro_cfg.format_tag = prtd->codec_param.codec.format;
1096 wma_pro_cfg.ch_cfg = prtd->codec_param.codec.ch_in;
1097 wma_pro_cfg.sample_rate = prtd->sample_rate;
1098 wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8;
1099 wma_pro_cfg.block_align = codec_options->wma.super_block_align;
1100 wma_pro_cfg.valid_bits_per_sample =
1101 codec_options->wma.bits_per_sample;
1102 wma_pro_cfg.ch_mask = codec_options->wma.channelmask;
1103 wma_pro_cfg.encode_opt = codec_options->wma.encodeopt;
1104 wma_pro_cfg.adv_encode_opt = codec_options->wma.encodeopt1;
1105 wma_pro_cfg.adv_encode_opt2 = codec_options->wma.encodeopt2;
1106 ret = q6asm_media_format_block_wmapro(prtd->audio_client,
1107 &wma_pro_cfg, stream_id);
1108 if (ret < 0)
1109 pr_err("%s: CMD Format block failed\n", __func__);
1110 break;
1111 case FORMAT_MP2:
1112 pr_debug("%s: SND_AUDIOCODEC_MP2\n", __func__);
1113 break;
1114 case FORMAT_FLAC:
1115 pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
1116 memset(&flac_cfg, 0x0, sizeof(struct asm_flac_cfg));
1117 flac_cfg.ch_cfg = prtd->num_channels;
1118 flac_cfg.sample_rate = prtd->sample_rate;
1119 flac_cfg.stream_info_present = 1;
1120 flac_cfg.sample_size = codec_options->flac_dec.sample_size;
1121 flac_cfg.min_blk_size = codec_options->flac_dec.min_blk_size;
1122 flac_cfg.max_blk_size = codec_options->flac_dec.max_blk_size;
1123 flac_cfg.max_frame_size =
1124 codec_options->flac_dec.max_frame_size;
1125 flac_cfg.min_frame_size =
1126 codec_options->flac_dec.min_frame_size;
1127
1128 ret = q6asm_stream_media_format_block_flac(prtd->audio_client,
1129 &flac_cfg, stream_id);
1130 if (ret < 0)
1131 pr_err("%s: CMD Format block failed ret %d\n",
1132 __func__, ret);
1133
1134 break;
1135 case FORMAT_VORBIS:
1136 pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__);
1137 memset(&vorbis_cfg, 0x0, sizeof(struct asm_vorbis_cfg));
1138 vorbis_cfg.bit_stream_fmt =
1139 codec_options->vorbis_dec.bit_stream_fmt;
1140
1141 ret = q6asm_stream_media_format_block_vorbis(
1142 prtd->audio_client, &vorbis_cfg,
1143 stream_id);
1144 if (ret < 0)
1145 pr_err("%s: CMD Format block failed ret %d\n",
1146 __func__, ret);
1147
1148 break;
1149 case FORMAT_ALAC:
1150 pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__);
1151 memset(&alac_cfg, 0x0, sizeof(struct asm_alac_cfg));
1152 alac_cfg.num_channels = prtd->num_channels;
1153 alac_cfg.sample_rate = prtd->sample_rate;
1154 alac_cfg.frame_length = codec_options->alac.frame_length;
1155 alac_cfg.compatible_version =
1156 codec_options->alac.compatible_version;
1157 alac_cfg.bit_depth = codec_options->alac.bit_depth;
1158 alac_cfg.pb = codec_options->alac.pb;
1159 alac_cfg.mb = codec_options->alac.mb;
1160 alac_cfg.kb = codec_options->alac.kb;
1161 alac_cfg.max_run = codec_options->alac.max_run;
1162 alac_cfg.max_frame_bytes = codec_options->alac.max_frame_bytes;
1163 alac_cfg.avg_bit_rate = codec_options->alac.avg_bit_rate;
1164 alac_cfg.channel_layout_tag =
1165 codec_options->alac.channel_layout_tag;
1166
1167 ret = q6asm_media_format_block_alac(prtd->audio_client,
1168 &alac_cfg, stream_id);
1169 if (ret < 0)
1170 pr_err("%s: CMD Format block failed ret %d\n",
1171 __func__, ret);
1172 break;
1173 case FORMAT_APE:
1174 pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__);
1175 memset(&ape_cfg, 0x0, sizeof(struct asm_ape_cfg));
1176 ape_cfg.num_channels = prtd->num_channels;
1177 ape_cfg.sample_rate = prtd->sample_rate;
1178 ape_cfg.compatible_version =
1179 codec_options->ape.compatible_version;
1180 ape_cfg.compression_level =
1181 codec_options->ape.compression_level;
1182 ape_cfg.format_flags = codec_options->ape.format_flags;
1183 ape_cfg.blocks_per_frame = codec_options->ape.blocks_per_frame;
1184 ape_cfg.final_frame_blocks =
1185 codec_options->ape.final_frame_blocks;
1186 ape_cfg.total_frames = codec_options->ape.total_frames;
1187 ape_cfg.bits_per_sample = codec_options->ape.bits_per_sample;
1188 ape_cfg.seek_table_present =
1189 codec_options->ape.seek_table_present;
1190
1191 ret = q6asm_media_format_block_ape(prtd->audio_client,
1192 &ape_cfg, stream_id);
1193
1194 if (ret < 0)
1195 pr_err("%s: CMD Format block failed ret %d\n",
1196 __func__, ret);
1197 break;
1198 case FORMAT_DTS:
1199 pr_debug("SND_AUDIOCODEC_DTS\n");
1200 /* no media format block needed */
1201 break;
1202 case FORMAT_DSD:
1203 pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
1204 memset(&dsd_cfg, 0x0, sizeof(struct asm_dsd_cfg));
1205 dsd_cfg.num_channels = prtd->num_channels;
1206 dsd_cfg.dsd_data_rate = prtd->sample_rate;
1207 dsd_cfg.num_version = 0;
1208 dsd_cfg.is_bitwise_big_endian = 1;
1209 dsd_cfg.dsd_channel_block_size = 1;
1210 ret = q6asm_media_format_block_dsd(prtd->audio_client,
1211 &dsd_cfg, stream_id);
1212 if (ret < 0)
1213 pr_err("%s: CMD DSD Format block failed ret %d\n",
1214 __func__, ret);
1215 break;
1216 case FORMAT_TRUEHD:
1217 pr_debug("SND_AUDIOCODEC_TRUEHD\n");
1218 /* no media format block needed */
1219 break;
1220 case FORMAT_IEC61937:
1221 pr_debug("SND_AUDIOCODEC_IEC61937\n");
1222 ret = q6asm_media_format_block_iec(prtd->audio_client,
1223 prtd->sample_rate,
1224 prtd->num_channels);
1225 if (ret < 0)
1226 pr_err("%s: CMD IEC61937 Format block failed ret %d\n",
1227 __func__, ret);
1228 break;
1229 case FORMAT_APTX:
1230 pr_debug("SND_AUDIOCODEC_APTX\n");
1231 memset(&aptx_cfg, 0x0, sizeof(struct aptx_dec_bt_addr_cfg));
1232 ret = q6asm_stream_media_format_block_aptx_dec(
1233 prtd->audio_client,
1234 prtd->sample_rate,
1235 stream_id);
1236 if (ret >= 0) {
1237 aptx_cfg.nap = codec_options->aptx_dec.nap;
1238 aptx_cfg.uap = codec_options->aptx_dec.uap;
1239 aptx_cfg.lap = codec_options->aptx_dec.lap;
1240 q6asm_set_aptx_dec_bt_addr(prtd->audio_client,
1241 &aptx_cfg);
1242 } else {
1243 pr_err("%s: CMD Format block failed ret %d\n",
1244 __func__, ret);
1245 }
1246 break;
1247 default:
1248 pr_debug("%s, unsupported format, skip", __func__);
1249 break;
1250 }
1251 return ret;
1252}
1253
1254static int msm_compr_init_pp_params(struct snd_compr_stream *cstream,
1255 struct audio_client *ac)
1256{
1257 int ret = 0;
1258 struct asm_softvolume_params softvol = {
1259 .period = SOFT_VOLUME_PERIOD,
1260 .step = SOFT_VOLUME_STEP,
1261 .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
1262 };
1263
1264 switch (ac->topology) {
1265 default:
1266 ret = q6asm_set_softvolume_v2(ac, &softvol,
1267 SOFT_VOLUME_INSTANCE_1);
1268 if (ret < 0)
1269 pr_err("%s: Send SoftVolume Param failed ret=%d\n",
1270 __func__, ret);
1271
1272 break;
1273 }
1274 return ret;
1275}
1276
1277static int msm_compr_configure_dsp_for_playback
1278 (struct snd_compr_stream *cstream)
1279{
1280 struct snd_compr_runtime *runtime = cstream->runtime;
1281 struct msm_compr_audio *prtd = runtime->private_data;
1282 struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data;
1283 uint16_t bits_per_sample = 16;
1284 int dir = IN, ret = 0;
1285 struct audio_client *ac = prtd->audio_client;
1286 uint32_t stream_index;
1287 struct asm_softpause_params softpause = {
1288 .enable = SOFT_PAUSE_ENABLE,
1289 .period = SOFT_PAUSE_PERIOD,
1290 .step = SOFT_PAUSE_STEP,
1291 .rampingcurve = SOFT_PAUSE_CURVE_LINEAR,
1292 };
1293 struct asm_softvolume_params softvol = {
1294 .period = SOFT_VOLUME_PERIOD,
1295 .step = SOFT_VOLUME_STEP,
1296 .rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
1297 };
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301298 struct snd_kcontrol *kctl;
1299 struct snd_ctl_elem_value kctl_elem_value;
1300 uint16_t target_asm_bit_width = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301301
1302 pr_debug("%s: stream_id %d\n", __func__, ac->stream_id);
1303 stream_index = STREAM_ARRAY_INDEX(ac->stream_id);
1304 if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) {
1305 pr_err("%s: Invalid stream index:%d", __func__, stream_index);
1306 return -EINVAL;
1307 }
1308
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301309 kctl = snd_soc_card_get_kcontrol(soc_prtd->card,
1310 DSP_BIT_WIDTH_MIXER_CTL);
1311 if (kctl) {
1312 kctl->get(kctl, &kctl_elem_value);
1313 target_asm_bit_width = kctl_elem_value.value.integer.value[0];
1314 if (target_asm_bit_width > 0) {
1315 pr_debug("%s enforce ASM bitwidth to %d from %d\n",
1316 __func__,
1317 target_asm_bit_width,
1318 bits_per_sample);
1319 bits_per_sample = target_asm_bit_width;
1320 }
1321 } else {
1322 pr_info("%s: failed to get mixer ctl for %s.\n",
1323 __func__, DSP_BIT_WIDTH_MIXER_CTL);
1324 }
1325
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301326 if ((prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) ||
1327 (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_3LE))
1328 bits_per_sample = 24;
1329 else if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S32_LE)
1330 bits_per_sample = 32;
1331
1332 if (prtd->compr_passthr != LEGACY_PCM) {
1333 ret = q6asm_open_write_compressed(ac, prtd->codec,
1334 prtd->compr_passthr);
1335 if (ret < 0) {
1336 pr_err("%s:ASM open write err[%d] for compr_type[%d]\n",
1337 __func__, ret, prtd->compr_passthr);
1338 return ret;
1339 }
1340 prtd->gapless_state.stream_opened[stream_index] = 1;
1341
1342 ret = msm_pcm_routing_reg_phy_compr_stream(
1343 soc_prtd->dai_link->id,
1344 ac->perf_mode,
1345 prtd->session_id,
1346 SNDRV_PCM_STREAM_PLAYBACK,
1347 prtd->compr_passthr);
1348 if (ret) {
1349 pr_err("%s: compr stream reg failed:%d\n", __func__,
1350 ret);
1351 return ret;
1352 }
1353 } else {
1354 pr_debug("%s: stream_id %d bits_per_sample %d\n",
1355 __func__, ac->stream_id, bits_per_sample);
Dieter Lueckingceef9af2018-09-28 15:09:32 +02001356
1357 if (q6core_get_avcs_api_version_per_service(
1358 APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
1359 ADSP_ASM_API_VERSION_V2)
1360 ret = q6asm_stream_open_write_v5(ac,
1361 prtd->codec, bits_per_sample,
1362 ac->stream_id,
1363 prtd->gapless_state.use_dsp_gapless_mode);
1364 else
1365 ret = q6asm_stream_open_write_v4(ac,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301366 prtd->codec, bits_per_sample,
1367 ac->stream_id,
1368 prtd->gapless_state.use_dsp_gapless_mode);
1369 if (ret < 0) {
1370 pr_err("%s:ASM open write err[%d] for compr type[%d]\n",
1371 __func__, ret, prtd->compr_passthr);
1372 return -ENOMEM;
1373 }
1374 prtd->gapless_state.stream_opened[stream_index] = 1;
1375
1376 pr_debug("%s: BE id %d\n", __func__, soc_prtd->dai_link->id);
1377 ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id,
1378 ac->perf_mode,
1379 prtd->session_id,
1380 SNDRV_PCM_STREAM_PLAYBACK);
1381 if (ret) {
1382 pr_err("%s: stream reg failed:%d\n", __func__, ret);
1383 return ret;
1384 }
1385 }
1386
1387 ret = msm_compr_set_volume(cstream, 0, 0);
1388 if (ret < 0)
1389 pr_err("%s : Set Volume failed : %d", __func__, ret);
1390
1391 if (prtd->compr_passthr != LEGACY_PCM) {
1392 pr_debug("%s : Don't send cal and PP params for compress path",
1393 __func__);
1394 } else {
1395 ret = q6asm_send_cal(ac);
1396 if (ret < 0)
1397 pr_debug("%s : Send cal failed : %d", __func__, ret);
1398
1399 ret = q6asm_set_softpause(ac, &softpause);
1400 if (ret < 0)
1401 pr_err("%s: Send SoftPause Param failed ret=%d\n",
1402 __func__, ret);
1403
1404 ret = q6asm_set_softvolume(ac, &softvol);
1405 if (ret < 0)
1406 pr_err("%s: Send SoftVolume Param failed ret=%d\n",
1407 __func__, ret);
1408 }
1409 ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
1410 if (ret < 0) {
1411 pr_err("%s: Set IO mode failed\n", __func__);
1412 return -EINVAL;
1413 }
1414
1415 runtime->fragments = prtd->codec_param.buffer.fragments;
1416 runtime->fragment_size = prtd->codec_param.buffer.fragment_size;
1417 pr_debug("allocate %d buffers each of size %d\n",
1418 runtime->fragments,
1419 runtime->fragment_size);
1420 ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac,
1421 runtime->fragment_size,
1422 runtime->fragments);
1423 if (ret < 0) {
1424 pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret);
1425 return -ENOMEM;
1426 }
1427
1428 prtd->byte_offset = 0;
1429 prtd->copied_total = 0;
1430 prtd->app_pointer = 0;
1431 prtd->bytes_received = 0;
1432 prtd->bytes_sent = 0;
1433 prtd->buffer = ac->port[dir].buf[0].data;
1434 prtd->buffer_paddr = ac->port[dir].buf[0].phys;
1435 prtd->buffer_size = runtime->fragments * runtime->fragment_size;
1436
1437 /* Bit-0 of flags represent timestamp mode */
1438 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG)
1439 prtd->ts_header_offset = sizeof(struct snd_codec_metadata);
1440 else
1441 prtd->ts_header_offset = 0;
1442
1443 ret = msm_compr_send_media_format_block(cstream, ac->stream_id, false);
1444 if (ret < 0)
1445 pr_err("%s, failed to send media format block\n", __func__);
1446
1447 return ret;
1448}
1449
1450static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
1451{
1452 struct snd_compr_runtime *runtime = cstream->runtime;
1453 struct msm_compr_audio *prtd = runtime->private_data;
1454 struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data;
1455 uint16_t bits_per_sample;
1456 uint16_t sample_word_size;
1457 int dir = OUT, ret = 0;
1458 struct audio_client *ac = prtd->audio_client;
1459 uint32_t stream_index;
Vikram Pandurangac712c172017-11-17 17:36:49 -08001460 uint32_t enc_cfg_id = ENC_CFG_ID_NONE;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301461
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;
Vikram Pandurangac712c172017-11-17 17:36:49 -08001479 if (prtd->codec == FORMAT_BESPOKE)
1480 enc_cfg_id =
1481 prtd->codec_param.codec.options.generic.reserved[0];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301482 break;
1483 }
1484
Ralf Herz22573552018-06-20 11:30:58 +02001485 pr_debug("%s: stream_id %d bits_per_sample %d compr_passthr %d\n",
1486 __func__, ac->stream_id, bits_per_sample,
1487 prtd->compr_passthr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301488
Ralf Herz22573552018-06-20 11:30:58 +02001489 if (prtd->compr_passthr != LEGACY_PCM) {
1490 ret = q6asm_open_read_compressed(prtd->audio_client,
1491 prtd->codec, prtd->compr_passthr);
1492 if (ret < 0) {
1493 pr_err("%s:ASM open read err[%d] for compr_type[%d]\n",
1494 __func__, ret, prtd->compr_passthr);
1495 return ret;
1496 }
1497
1498 ret = msm_pcm_routing_reg_phy_compr_stream(
1499 soc_prtd->dai_link->id,
1500 ac->perf_mode,
1501 prtd->session_id,
1502 SNDRV_PCM_STREAM_CAPTURE,
1503 prtd->compr_passthr);
1504 if (ret) {
1505 pr_err("%s: compr stream reg failed:%d\n",
1506 __func__, ret);
1507 return ret;
1508 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301509 } else {
Ralf Herz22573552018-06-20 11:30:58 +02001510 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
1511 ret = q6asm_open_read_v4(prtd->audio_client,
1512 prtd->codec,
1513 bits_per_sample, true, enc_cfg_id);
1514 } else {
1515 ret = q6asm_open_read_v4(prtd->audio_client,
1516 prtd->codec,
1517 bits_per_sample, false, enc_cfg_id);
1518 }
1519 if (ret < 0) {
1520 pr_err("%s: q6asm_open_read failed:%d\n",
1521 __func__, ret);
1522 return ret;
1523 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301524
Ralf Herz22573552018-06-20 11:30:58 +02001525 ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id,
1526 ac->perf_mode,
1527 prtd->session_id,
1528 SNDRV_PCM_STREAM_CAPTURE);
1529 if (ret) {
1530 pr_err("%s: stream reg failed:%d\n", __func__, ret);
1531 return ret;
1532 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301533 }
1534
1535 ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
1536 if (ret < 0) {
1537 pr_err("%s: Set IO mode failed\n", __func__);
1538 return -EINVAL;
1539 }
1540
1541 stream_index = STREAM_ARRAY_INDEX(ac->stream_id);
1542 if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) {
1543 pr_err("%s: Invalid stream index:%d", __func__, stream_index);
1544 return -EINVAL;
1545 }
1546
1547 runtime->fragments = prtd->codec_param.buffer.fragments;
1548 runtime->fragment_size = prtd->codec_param.buffer.fragment_size;
1549 pr_debug("%s: allocate %d buffers each of size %d\n",
1550 __func__, runtime->fragments,
1551 runtime->fragment_size);
1552 ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac,
1553 runtime->fragment_size,
1554 runtime->fragments);
1555 if (ret < 0) {
1556 pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret);
1557 return -ENOMEM;
1558 }
1559
1560 prtd->byte_offset = 0;
1561 prtd->received_total = 0;
1562 prtd->app_pointer = 0;
1563 prtd->bytes_copied = 0;
1564 prtd->bytes_read = 0;
1565 prtd->bytes_read_offset = 0;
1566 prtd->buffer = ac->port[dir].buf[0].data;
1567 prtd->buffer_paddr = ac->port[dir].buf[0].phys;
1568 prtd->buffer_size = runtime->fragments * runtime->fragment_size;
1569
1570 /* Bit-0 of flags represent timestamp mode */
1571 if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG)
1572 prtd->ts_header_offset = sizeof(struct snd_codec_metadata);
1573 else
1574 prtd->ts_header_offset = 0;
1575
1576 pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
1577 __func__, prtd->sample_rate, prtd->num_channels,
1578 bits_per_sample, sample_word_size);
Vikram Pandurangac712c172017-11-17 17:36:49 -08001579 if (prtd->codec == FORMAT_BESPOKE) {
1580 /*
1581 * For BESPOKE codec, encoder specific config params are
1582 * included as part of generic.
1583 */
1584 ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate,
1585 prtd->num_channels, prtd->codec,
1586 (void *)&prtd->codec_param.codec.options.generic);
Ralf Herz22573552018-06-20 11:30:58 +02001587 } else if (prtd->compr_passthr == LEGACY_PCM) {
Vikram Pandurangac712c172017-11-17 17:36:49 -08001588 ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301589 prtd->sample_rate, prtd->num_channels,
Sachin Mohan Gadag7c944232018-01-04 11:04:00 +05301590 bits_per_sample, sample_word_size,
1591 ASM_LITTLE_ENDIAN, DEFAULT_QF);
Vikram Pandurangac712c172017-11-17 17:36:49 -08001592 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301593
1594 return ret;
1595}
1596
1597static int msm_compr_playback_open(struct snd_compr_stream *cstream)
1598{
1599 struct snd_compr_runtime *runtime = cstream->runtime;
1600 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
Aditya Bavanari9deef912017-11-20 13:31:31 +05301601 struct msm_compr_audio *prtd = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301602 struct msm_compr_pdata *pdata =
1603 snd_soc_platform_get_drvdata(rtd->platform);
1604
1605 pr_debug("%s\n", __func__);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301606 if (pdata->is_in_use[rtd->dai_link->id] == true) {
1607 pr_err("%s: %s is already in use, err: %d\n",
1608 __func__, rtd->dai_link->cpu_dai_name, -EBUSY);
1609 return -EBUSY;
1610 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301611 prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
1612 if (prtd == NULL) {
1613 pr_err("Failed to allocate memory for msm_compr_audio\n");
1614 return -ENOMEM;
1615 }
1616
1617 runtime->private_data = NULL;
1618 prtd->cstream = cstream;
1619 pdata->cstream[rtd->dai_link->id] = cstream;
1620 pdata->audio_effects[rtd->dai_link->id] =
1621 kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301622 if (pdata->audio_effects[rtd->dai_link->id] == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301623 pr_err("%s: Could not allocate memory for effects\n", __func__);
1624 pdata->cstream[rtd->dai_link->id] = NULL;
1625 kfree(prtd);
1626 return -ENOMEM;
1627 }
1628 pdata->dec_params[rtd->dai_link->id] =
1629 kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301630 if (pdata->dec_params[rtd->dai_link->id] == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301631 pr_err("%s: Could not allocate memory for dec params\n",
1632 __func__);
1633 kfree(pdata->audio_effects[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301634 pdata->audio_effects[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301635 pdata->cstream[rtd->dai_link->id] = NULL;
1636 kfree(prtd);
1637 return -ENOMEM;
1638 }
1639 prtd->codec = FORMAT_MP3;
1640 prtd->bytes_received = 0;
1641 prtd->bytes_sent = 0;
1642 prtd->copied_total = 0;
1643 prtd->byte_offset = 0;
1644 prtd->sample_rate = 44100;
1645 prtd->num_channels = 2;
1646 prtd->drain_ready = 0;
1647 prtd->last_buffer = 0;
1648 prtd->first_buffer = 1;
1649 prtd->partial_drain_delay = 0;
1650 prtd->next_stream = 0;
1651 memset(&prtd->gapless_state, 0, sizeof(struct msm_compr_gapless_state));
1652 /*
1653 * Update the use_dsp_gapless_mode from gapless struture with the value
1654 * part of platform data.
1655 */
1656 prtd->gapless_state.use_dsp_gapless_mode = pdata->use_dsp_gapless_mode;
1657
1658 pr_debug("%s: gapless mode %d", __func__, pdata->use_dsp_gapless_mode);
1659
1660 spin_lock_init(&prtd->lock);
1661
1662 atomic_set(&prtd->eos, 0);
1663 atomic_set(&prtd->start, 0);
1664 atomic_set(&prtd->drain, 0);
1665 atomic_set(&prtd->xrun, 0);
1666 atomic_set(&prtd->close, 0);
1667 atomic_set(&prtd->wait_on_close, 0);
1668 atomic_set(&prtd->error, 0);
1669
1670 init_waitqueue_head(&prtd->eos_wait);
1671 init_waitqueue_head(&prtd->drain_wait);
1672 init_waitqueue_head(&prtd->close_wait);
1673 init_waitqueue_head(&prtd->wait_for_stream_avail);
1674
1675 runtime->private_data = prtd;
1676 populate_codec_list(prtd);
1677 prtd->audio_client = q6asm_audio_client_alloc(
1678 (app_cb)compr_event_handler, prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301679 if (prtd->audio_client == NULL) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301680 pr_err("%s: Could not allocate memory for client\n", __func__);
1681 kfree(pdata->audio_effects[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301682 pdata->audio_effects[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301683 kfree(pdata->dec_params[rtd->dai_link->id]);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301684 pdata->dec_params[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301685 pdata->cstream[rtd->dai_link->id] = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301686 kfree(prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301687 runtime->private_data = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301688 return -ENOMEM;
1689 }
1690 pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session);
1691 prtd->audio_client->perf_mode = false;
1692 prtd->session_id = prtd->audio_client->session;
1693 msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301694 pdata->is_in_use[rtd->dai_link->id] = true;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301695 return 0;
1696}
1697
1698static int msm_compr_capture_open(struct snd_compr_stream *cstream)
1699{
1700 struct snd_compr_runtime *runtime = cstream->runtime;
1701 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
1702 struct msm_compr_audio *prtd;
1703 struct msm_compr_pdata *pdata =
1704 snd_soc_platform_get_drvdata(rtd->platform);
1705
1706 pr_debug("%s\n", __func__);
1707 prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
1708 if (prtd == NULL) {
1709 pr_err("Failed to allocate memory for msm_compr_audio\n");
1710 return -ENOMEM;
1711 }
1712
1713 runtime->private_data = NULL;
1714 prtd->cstream = cstream;
1715 pdata->cstream[rtd->dai_link->id] = cstream;
1716
1717 prtd->audio_client = q6asm_audio_client_alloc(
1718 (app_cb)compr_event_handler, prtd);
1719 if (!prtd->audio_client) {
1720 pr_err("%s: Could not allocate memory for client\n", __func__);
1721 pdata->cstream[rtd->dai_link->id] = NULL;
1722 kfree(prtd);
1723 return -ENOMEM;
1724 }
1725 pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session);
1726 prtd->audio_client->perf_mode = false;
1727 prtd->session_id = prtd->audio_client->session;
1728 prtd->codec = FORMAT_LINEAR_PCM;
1729 prtd->bytes_copied = 0;
1730 prtd->bytes_read = 0;
1731 prtd->bytes_read_offset = 0;
1732 prtd->received_total = 0;
1733 prtd->byte_offset = 0;
1734 prtd->sample_rate = 48000;
1735 prtd->num_channels = 2;
1736 prtd->first_buffer = 0;
1737
1738 spin_lock_init(&prtd->lock);
1739
1740 atomic_set(&prtd->eos, 0);
1741 atomic_set(&prtd->start, 0);
1742 atomic_set(&prtd->drain, 0);
1743 atomic_set(&prtd->xrun, 0);
1744 atomic_set(&prtd->close, 0);
1745 atomic_set(&prtd->wait_on_close, 0);
1746 atomic_set(&prtd->error, 0);
1747
1748 runtime->private_data = prtd;
1749
1750 return 0;
1751}
1752
1753static int msm_compr_open(struct snd_compr_stream *cstream)
1754{
1755 int ret = 0;
1756
1757 if (cstream->direction == SND_COMPRESS_PLAYBACK)
1758 ret = msm_compr_playback_open(cstream);
1759 else if (cstream->direction == SND_COMPRESS_CAPTURE)
1760 ret = msm_compr_capture_open(cstream);
1761 return ret;
1762}
1763
1764static int msm_compr_playback_free(struct snd_compr_stream *cstream)
1765{
1766 struct snd_compr_runtime *runtime;
1767 struct msm_compr_audio *prtd;
1768 struct snd_soc_pcm_runtime *soc_prtd;
1769 struct msm_compr_pdata *pdata;
1770 struct audio_client *ac;
1771 int dir = IN, ret = 0, stream_id;
1772 unsigned long flags;
1773 uint32_t stream_index;
1774
1775 pr_debug("%s\n", __func__);
1776
1777 if (!cstream) {
1778 pr_err("%s cstream is null\n", __func__);
1779 return 0;
1780 }
1781 runtime = cstream->runtime;
1782 soc_prtd = cstream->private_data;
1783 if (!runtime || !soc_prtd || !(soc_prtd->platform)) {
1784 pr_err("%s runtime or soc_prtd or platform is null\n",
1785 __func__);
1786 return 0;
1787 }
1788 prtd = runtime->private_data;
1789 if (!prtd) {
1790 pr_err("%s prtd is null\n", __func__);
1791 return 0;
1792 }
1793 prtd->cmd_interrupt = 1;
1794 wake_up(&prtd->drain_wait);
1795 pdata = snd_soc_platform_get_drvdata(soc_prtd->platform);
1796 ac = prtd->audio_client;
1797 if (!pdata || !ac) {
1798 pr_err("%s pdata or ac is null\n", __func__);
1799 return 0;
1800 }
1801 if (atomic_read(&prtd->eos)) {
1802 ret = wait_event_timeout(prtd->eos_wait,
1803 prtd->eos_ack, 5 * HZ);
1804 if (!ret)
1805 pr_err("%s: CMD_EOS failed\n", __func__);
1806 }
1807 if (atomic_read(&prtd->close)) {
1808 prtd->cmd_ack = 0;
1809 atomic_set(&prtd->wait_on_close, 1);
1810 ret = wait_event_timeout(prtd->close_wait,
1811 prtd->cmd_ack, 5 * HZ);
1812 if (!ret)
1813 pr_err("%s: CMD_CLOSE failed\n", __func__);
1814 }
1815
1816 spin_lock_irqsave(&prtd->lock, flags);
1817 stream_id = ac->stream_id;
1818 stream_index = STREAM_ARRAY_INDEX(NEXT_STREAM_ID(stream_id));
1819
1820 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
1821 (prtd->gapless_state.stream_opened[stream_index])) {
1822 prtd->gapless_state.stream_opened[stream_index] = 0;
1823 spin_unlock_irqrestore(&prtd->lock, flags);
1824 pr_debug(" close stream %d", NEXT_STREAM_ID(stream_id));
1825 q6asm_stream_cmd(ac, CMD_CLOSE, NEXT_STREAM_ID(stream_id));
1826 spin_lock_irqsave(&prtd->lock, flags);
1827 }
1828
1829 stream_index = STREAM_ARRAY_INDEX(stream_id);
1830 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) &&
1831 (prtd->gapless_state.stream_opened[stream_index])) {
1832 prtd->gapless_state.stream_opened[stream_index] = 0;
1833 spin_unlock_irqrestore(&prtd->lock, flags);
1834 pr_debug("close stream %d", stream_id);
1835 q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
1836 spin_lock_irqsave(&prtd->lock, flags);
1837 }
1838 spin_unlock_irqrestore(&prtd->lock, flags);
1839
1840 pdata->cstream[soc_prtd->dai_link->id] = NULL;
1841 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
1842 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
1843 SNDRV_PCM_STREAM_PLAYBACK);
1844 }
1845
1846 q6asm_audio_client_buf_free_contiguous(dir, ac);
1847
1848 q6asm_audio_client_free(ac);
1849 msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd);
Aditya Bavanari9deef912017-11-20 13:31:31 +05301850 if (pdata->audio_effects[soc_prtd->dai_link->id] != NULL) {
1851 kfree(pdata->audio_effects[soc_prtd->dai_link->id]);
1852 pdata->audio_effects[soc_prtd->dai_link->id] = NULL;
1853 }
1854 if (pdata->dec_params[soc_prtd->dai_link->id] != NULL) {
1855 kfree(pdata->dec_params[soc_prtd->dai_link->id]);
1856 pdata->dec_params[soc_prtd->dai_link->id] = NULL;
1857 }
1858 pdata->is_in_use[soc_prtd->dai_link->id] = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301859 kfree(prtd);
1860 runtime->private_data = NULL;
1861
1862 return 0;
1863}
1864
1865static int msm_compr_capture_free(struct snd_compr_stream *cstream)
1866{
1867 struct snd_compr_runtime *runtime;
1868 struct msm_compr_audio *prtd;
1869 struct snd_soc_pcm_runtime *soc_prtd;
1870 struct msm_compr_pdata *pdata;
1871 struct audio_client *ac;
1872 int dir = OUT, stream_id;
1873 unsigned long flags;
1874 uint32_t stream_index;
1875
1876 if (!cstream) {
1877 pr_err("%s cstream is null\n", __func__);
1878 return 0;
1879 }
1880 runtime = cstream->runtime;
1881 soc_prtd = cstream->private_data;
1882 if (!runtime || !soc_prtd || !(soc_prtd->platform)) {
1883 pr_err("%s runtime or soc_prtd or platform is null\n",
1884 __func__);
1885 return 0;
1886 }
1887 prtd = runtime->private_data;
1888 if (!prtd) {
1889 pr_err("%s prtd is null\n", __func__);
1890 return 0;
1891 }
1892 pdata = snd_soc_platform_get_drvdata(soc_prtd->platform);
1893 ac = prtd->audio_client;
1894 if (!pdata || !ac) {
1895 pr_err("%s pdata or ac is null\n", __func__);
1896 return 0;
1897 }
1898
1899 spin_lock_irqsave(&prtd->lock, flags);
1900 stream_id = ac->stream_id;
1901
1902 stream_index = STREAM_ARRAY_INDEX(stream_id);
1903 if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0)) {
1904 spin_unlock_irqrestore(&prtd->lock, flags);
1905 pr_debug("close stream %d", stream_id);
1906 q6asm_stream_cmd(ac, CMD_CLOSE, stream_id);
1907 spin_lock_irqsave(&prtd->lock, flags);
1908 }
1909 spin_unlock_irqrestore(&prtd->lock, flags);
1910
1911 pdata->cstream[soc_prtd->dai_link->id] = NULL;
1912 msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
1913 SNDRV_PCM_STREAM_CAPTURE);
1914
1915 q6asm_audio_client_buf_free_contiguous(dir, ac);
1916
1917 q6asm_audio_client_free(ac);
1918
1919 kfree(prtd);
1920 runtime->private_data = NULL;
1921
1922 return 0;
1923}
1924
1925static int msm_compr_free(struct snd_compr_stream *cstream)
1926{
1927 int ret = 0;
1928
1929 if (cstream->direction == SND_COMPRESS_PLAYBACK)
1930 ret = msm_compr_playback_free(cstream);
1931 else if (cstream->direction == SND_COMPRESS_CAPTURE)
1932 ret = msm_compr_capture_free(cstream);
1933 return ret;
1934}
1935
1936static bool msm_compr_validate_codec_compr(__u32 codec_id)
1937{
1938 int32_t i;
1939
1940 for (i = 0; i < ARRAY_SIZE(compr_codecs); i++) {
1941 if (compr_codecs[i] == codec_id)
1942 return true;
1943 }
1944 return false;
1945}
1946
1947/* compress stream operations */
1948static int msm_compr_set_params(struct snd_compr_stream *cstream,
1949 struct snd_compr_params *params)
1950{
1951 struct snd_compr_runtime *runtime = cstream->runtime;
1952 struct msm_compr_audio *prtd = runtime->private_data;
1953 int ret = 0, frame_sz = 0;
1954 int i, num_rates;
1955 bool is_format_gapless = false;
1956
1957 pr_debug("%s\n", __func__);
1958
1959 num_rates = sizeof(supported_sample_rates)/sizeof(unsigned int);
1960 for (i = 0; i < num_rates; i++)
1961 if (params->codec.sample_rate == supported_sample_rates[i])
1962 break;
1963 if (i == num_rates)
1964 return -EINVAL;
1965
1966 memcpy(&prtd->codec_param, params, sizeof(struct snd_compr_params));
1967 /* ToDo: remove duplicates */
1968 prtd->num_channels = prtd->codec_param.codec.ch_in;
1969 prtd->sample_rate = prtd->codec_param.codec.sample_rate;
1970 pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
1971
1972 if ((prtd->codec_param.codec.compr_passthr >= LEGACY_PCM &&
1973 prtd->codec_param.
1974 codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD) ||
1975 (prtd->codec_param.
1976 codec.compr_passthr == COMPRESSED_PASSTHROUGH_IEC61937))
1977 prtd->compr_passthr = prtd->codec_param.codec.compr_passthr;
1978 else
1979 prtd->compr_passthr = LEGACY_PCM;
1980 pr_debug("%s: compr_passthr = %d", __func__, prtd->compr_passthr);
1981 if (prtd->compr_passthr != LEGACY_PCM) {
1982 pr_debug("%s: Reset gapless mode playback for compr_type[%d]\n",
1983 __func__, prtd->compr_passthr);
1984 prtd->gapless_state.use_dsp_gapless_mode = 0;
1985 if (!msm_compr_validate_codec_compr(params->codec.id)) {
1986 pr_err("%s codec not supported in passthrough,id =%d\n",
1987 __func__, params->codec.id);
1988 return -EINVAL;
1989 }
1990 }
1991
1992 switch (params->codec.id) {
1993 case SND_AUDIOCODEC_PCM: {
1994 pr_debug("SND_AUDIOCODEC_PCM\n");
1995 prtd->codec = FORMAT_LINEAR_PCM;
1996 is_format_gapless = true;
1997 break;
1998 }
1999
2000 case SND_AUDIOCODEC_MP3: {
2001 pr_debug("SND_AUDIOCODEC_MP3\n");
2002 prtd->codec = FORMAT_MP3;
2003 frame_sz = MP3_OUTPUT_FRAME_SZ;
2004 is_format_gapless = true;
2005 break;
2006 }
2007
2008 case SND_AUDIOCODEC_AAC: {
2009 pr_debug("SND_AUDIOCODEC_AAC\n");
2010 prtd->codec = FORMAT_MPEG4_AAC;
2011 frame_sz = AAC_OUTPUT_FRAME_SZ;
2012 is_format_gapless = true;
2013 break;
2014 }
2015
2016 case SND_AUDIOCODEC_AC3: {
2017 pr_debug("SND_AUDIOCODEC_AC3\n");
2018 prtd->codec = FORMAT_AC3;
2019 frame_sz = AC3_OUTPUT_FRAME_SZ;
2020 is_format_gapless = true;
2021 break;
2022 }
2023
2024 case SND_AUDIOCODEC_EAC3: {
2025 pr_debug("SND_AUDIOCODEC_EAC3\n");
2026 prtd->codec = FORMAT_EAC3;
2027 frame_sz = EAC3_OUTPUT_FRAME_SZ;
2028 is_format_gapless = true;
2029 break;
2030 }
2031
2032 case SND_AUDIOCODEC_MP2: {
2033 pr_debug("SND_AUDIOCODEC_MP2\n");
2034 prtd->codec = FORMAT_MP2;
2035 break;
2036 }
2037
2038 case SND_AUDIOCODEC_WMA: {
2039 pr_debug("SND_AUDIOCODEC_WMA\n");
2040 prtd->codec = FORMAT_WMA_V9;
2041 break;
2042 }
2043
2044 case SND_AUDIOCODEC_WMA_PRO: {
2045 pr_debug("SND_AUDIOCODEC_WMA_PRO\n");
2046 prtd->codec = FORMAT_WMA_V10PRO;
2047 break;
2048 }
2049
2050 case SND_AUDIOCODEC_FLAC: {
2051 pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__);
2052 prtd->codec = FORMAT_FLAC;
2053 /*
2054 * DSP bufferring is based on blk size,
2055 * consider mininum buffering to rule out any false wait
2056 */
2057 frame_sz =
2058 prtd->codec_param.codec.options.flac_dec.min_blk_size;
2059 is_format_gapless = true;
2060 break;
2061 }
2062
2063 case SND_AUDIOCODEC_VORBIS: {
2064 pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__);
2065 prtd->codec = FORMAT_VORBIS;
2066 break;
2067 }
2068
2069 case SND_AUDIOCODEC_ALAC: {
2070 pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__);
2071 prtd->codec = FORMAT_ALAC;
2072 break;
2073 }
2074
2075 case SND_AUDIOCODEC_APE: {
2076 pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__);
2077 prtd->codec = FORMAT_APE;
2078 break;
2079 }
2080
2081 case SND_AUDIOCODEC_DTS: {
2082 pr_debug("%s: SND_AUDIOCODEC_DTS\n", __func__);
2083 prtd->codec = FORMAT_DTS;
2084 break;
2085 }
2086
2087 case SND_AUDIOCODEC_DSD: {
2088 pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
2089 prtd->codec = FORMAT_DSD;
2090 break;
2091 }
2092
2093 case SND_AUDIOCODEC_TRUEHD: {
2094 pr_debug("%s: SND_AUDIOCODEC_TRUEHD\n", __func__);
2095 prtd->codec = FORMAT_TRUEHD;
2096 break;
2097 }
2098
2099 case SND_AUDIOCODEC_IEC61937: {
2100 pr_debug("%s: SND_AUDIOCODEC_IEC61937\n", __func__);
2101 prtd->codec = FORMAT_IEC61937;
2102 break;
2103 }
2104
2105 case SND_AUDIOCODEC_APTX: {
2106 pr_debug("%s: SND_AUDIOCODEC_APTX\n", __func__);
2107 prtd->codec = FORMAT_APTX;
2108 break;
2109 }
2110
Vikram Pandurangac712c172017-11-17 17:36:49 -08002111 case SND_AUDIOCODEC_BESPOKE: {
2112 pr_debug("%s: SND_AUDIOCODEC_BESPOKE\n", __func__);
2113 prtd->codec = FORMAT_BESPOKE;
2114 break;
2115 }
2116
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302117 default:
2118 pr_err("codec not supported, id =%d\n", params->codec.id);
2119 return -EINVAL;
2120 }
2121
2122 if (!is_format_gapless)
2123 prtd->gapless_state.use_dsp_gapless_mode = false;
2124
2125 prtd->partial_drain_delay =
2126 msm_compr_get_partial_drain_delay(frame_sz, prtd->sample_rate);
2127
2128 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2129 ret = msm_compr_configure_dsp_for_playback(cstream);
2130 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2131 ret = msm_compr_configure_dsp_for_capture(cstream);
2132
2133 return ret;
2134}
2135
2136static int msm_compr_drain_buffer(struct msm_compr_audio *prtd,
2137 unsigned long *flags)
2138{
2139 int rc = 0;
2140
2141 atomic_set(&prtd->drain, 1);
2142 prtd->drain_ready = 0;
2143 spin_unlock_irqrestore(&prtd->lock, *flags);
2144 pr_debug("%s: wait for buffer to be drained\n", __func__);
2145 rc = wait_event_interruptible(prtd->drain_wait,
2146 prtd->drain_ready ||
2147 prtd->cmd_interrupt ||
2148 atomic_read(&prtd->xrun) ||
2149 atomic_read(&prtd->error));
2150 pr_debug("%s: out of buffer drain wait with ret %d\n", __func__, rc);
2151 spin_lock_irqsave(&prtd->lock, *flags);
2152 if (prtd->cmd_interrupt) {
2153 pr_debug("%s: buffer drain interrupted by flush)\n", __func__);
2154 rc = -EINTR;
2155 prtd->cmd_interrupt = 0;
2156 }
2157 if (atomic_read(&prtd->error)) {
2158 pr_err("%s: Got RESET EVENTS notification, return\n",
2159 __func__);
2160 rc = -ENETRESET;
2161 }
2162 return rc;
2163}
2164
2165static int msm_compr_wait_for_stream_avail(struct msm_compr_audio *prtd,
2166 unsigned long *flags)
2167{
2168 int rc = 0;
2169
2170 pr_debug("next session is already in opened state\n");
2171 prtd->next_stream = 1;
2172 prtd->cmd_interrupt = 0;
2173 spin_unlock_irqrestore(&prtd->lock, *flags);
2174 /*
2175 * Wait for stream to be available, or the wait to be interrupted by
2176 * commands like flush or till a timeout of one second.
2177 */
2178 rc = wait_event_timeout(prtd->wait_for_stream_avail,
2179 prtd->stream_available || prtd->cmd_interrupt, 1 * HZ);
2180 pr_err("%s:prtd->stream_available %d, prtd->cmd_interrupt %d rc %d\n",
2181 __func__, prtd->stream_available, prtd->cmd_interrupt, rc);
2182
2183 spin_lock_irqsave(&prtd->lock, *flags);
2184 if (rc == 0) {
2185 pr_err("%s: wait_for_stream_avail timed out\n",
2186 __func__);
2187 rc = -ETIMEDOUT;
2188 } else if (prtd->cmd_interrupt == 1) {
2189 /*
2190 * This scenario might not happen as we do not allow
2191 * flush in transition state.
2192 */
2193 pr_debug("%s: wait_for_stream_avail interrupted\n", __func__);
2194 prtd->cmd_interrupt = 0;
2195 prtd->stream_available = 0;
2196 rc = -EINTR;
2197 } else {
2198 prtd->stream_available = 0;
2199 rc = 0;
2200 }
2201 pr_debug("%s : rc = %d", __func__, rc);
2202 return rc;
2203}
2204
2205static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
2206{
2207 struct snd_compr_runtime *runtime = cstream->runtime;
2208 struct msm_compr_audio *prtd = runtime->private_data;
2209 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
2210 struct msm_compr_pdata *pdata =
2211 snd_soc_platform_get_drvdata(rtd->platform);
2212 uint32_t *volume = pdata->volume[rtd->dai_link->id];
2213 struct audio_client *ac = prtd->audio_client;
2214 unsigned long fe_id = rtd->dai_link->id;
2215 int rc = 0;
2216 int bytes_to_write;
2217 unsigned long flags;
2218 int stream_id;
2219 uint32_t stream_index;
2220 uint16_t bits_per_sample = 16;
2221
2222 spin_lock_irqsave(&prtd->lock, flags);
2223 if (atomic_read(&prtd->error)) {
2224 pr_err("%s Got RESET EVENTS notification, return immediately",
2225 __func__);
2226 spin_unlock_irqrestore(&prtd->lock, flags);
2227 return 0;
2228 }
2229 spin_unlock_irqrestore(&prtd->lock, flags);
2230
2231 switch (cmd) {
2232 case SNDRV_PCM_TRIGGER_START:
2233 pr_debug("%s: SNDRV_PCM_TRIGGER_START\n", __func__);
2234 atomic_set(&prtd->start, 1);
2235
2236 /*
2237 * compr_set_volume and compr_init_pp_params
2238 * are used to configure ASM volume hence not
2239 * needed for compress passthrough playback.
2240 *
2241 * compress passthrough volume is controlled in
2242 * ADM by adm_send_compressed_device_mute()
2243 */
2244 if (prtd->compr_passthr == LEGACY_PCM &&
2245 cstream->direction == SND_COMPRESS_PLAYBACK) {
2246 /* set volume for the stream before RUN */
2247 rc = msm_compr_set_volume(cstream,
2248 volume[0], volume[1]);
2249 if (rc)
2250 pr_err("%s : Set Volume failed : %d\n",
2251 __func__, rc);
2252
2253 rc = msm_compr_init_pp_params(cstream, ac);
2254 if (rc)
2255 pr_err("%s : init PP params failed : %d\n",
2256 __func__, rc);
2257 } else {
2258 msm_compr_read_buffer(prtd);
2259 }
2260 /* issue RUN command for the stream */
2261 q6asm_run_nowait(prtd->audio_client, prtd->run_mode,
2262 prtd->start_delay_msw, prtd->start_delay_lsw);
2263 break;
2264 case SNDRV_PCM_TRIGGER_STOP:
2265 spin_lock_irqsave(&prtd->lock, flags);
2266 pr_debug("%s: SNDRV_PCM_TRIGGER_STOP transition %d\n", __func__,
2267 prtd->gapless_state.gapless_transition);
2268 stream_id = ac->stream_id;
2269 atomic_set(&prtd->start, 0);
2270 if (cstream->direction == SND_COMPRESS_CAPTURE) {
2271 q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
2272 atomic_set(&prtd->xrun, 0);
2273 prtd->received_total = 0;
2274 prtd->bytes_copied = 0;
2275 prtd->bytes_read = 0;
2276 prtd->bytes_read_offset = 0;
2277 prtd->byte_offset = 0;
2278 prtd->app_pointer = 0;
2279 spin_unlock_irqrestore(&prtd->lock, flags);
2280 break;
2281 }
2282 if (prtd->next_stream) {
2283 pr_debug("%s: interrupt next track wait queues\n",
2284 __func__);
2285 prtd->cmd_interrupt = 1;
2286 wake_up(&prtd->wait_for_stream_avail);
2287 prtd->next_stream = 0;
2288 }
2289 if (atomic_read(&prtd->eos)) {
2290 pr_debug("%s: interrupt eos wait queues", __func__);
2291 /*
2292 * Gapless playback does not wait for eos, do not set
2293 * cmd_int and do not wake up eos_wait during gapless
2294 * transition
2295 */
2296 if (!prtd->gapless_state.gapless_transition) {
2297 prtd->cmd_interrupt = 1;
2298 wake_up(&prtd->eos_wait);
2299 }
2300 atomic_set(&prtd->eos, 0);
2301 }
2302 if (atomic_read(&prtd->drain)) {
2303 pr_debug("%s: interrupt drain wait queues", __func__);
2304 prtd->cmd_interrupt = 1;
2305 prtd->drain_ready = 1;
2306 wake_up(&prtd->drain_wait);
2307 atomic_set(&prtd->drain, 0);
2308 }
2309 prtd->last_buffer = 0;
2310 prtd->cmd_ack = 0;
2311 if (!prtd->gapless_state.gapless_transition) {
2312 pr_debug("issue CMD_FLUSH stream_id %d\n", stream_id);
2313 spin_unlock_irqrestore(&prtd->lock, flags);
2314 q6asm_stream_cmd(
2315 prtd->audio_client, CMD_FLUSH, stream_id);
2316 spin_lock_irqsave(&prtd->lock, flags);
2317 } else {
2318 prtd->first_buffer = 0;
2319 }
2320 /* FIXME. only reset if flush was successful */
2321 prtd->byte_offset = 0;
2322 prtd->copied_total = 0;
2323 prtd->app_pointer = 0;
2324 prtd->bytes_received = 0;
2325 prtd->bytes_sent = 0;
2326 prtd->marker_timestamp = 0;
2327
2328 atomic_set(&prtd->xrun, 0);
2329 spin_unlock_irqrestore(&prtd->lock, flags);
2330 break;
2331 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2332 pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH transition %d\n",
2333 prtd->gapless_state.gapless_transition);
2334 if (!prtd->gapless_state.gapless_transition) {
2335 pr_debug("issue CMD_PAUSE stream_id %d\n",
2336 ac->stream_id);
2337 q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
2338 atomic_set(&prtd->start, 0);
2339 }
2340 break;
2341 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2342 pr_debug("SNDRV_PCM_TRIGGER_PAUSE_RELEASE transition %d\n",
2343 prtd->gapless_state.gapless_transition);
2344 if (!prtd->gapless_state.gapless_transition) {
2345 atomic_set(&prtd->start, 1);
2346 q6asm_run_nowait(prtd->audio_client, prtd->run_mode,
2347 0, 0);
2348 }
2349 break;
2350 case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
2351 pr_debug("%s: SND_COMPR_TRIGGER_PARTIAL_DRAIN\n", __func__);
2352 if (!prtd->gapless_state.use_dsp_gapless_mode) {
2353 pr_debug("%s: set partial drain as drain\n", __func__);
2354 cmd = SND_COMPR_TRIGGER_DRAIN;
2355 }
2356 case SND_COMPR_TRIGGER_DRAIN:
2357 pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__);
2358 /* Make sure all the data is sent to DSP before sending EOS */
2359 spin_lock_irqsave(&prtd->lock, flags);
2360
2361 if (!atomic_read(&prtd->start)) {
2362 pr_err("%s: stream is not in started state\n",
2363 __func__);
2364 rc = -EPERM;
2365 spin_unlock_irqrestore(&prtd->lock, flags);
2366 break;
2367 }
2368 if (prtd->bytes_received > prtd->copied_total) {
2369 pr_debug("%s: wait till all the data is sent to dsp\n",
2370 __func__);
2371 rc = msm_compr_drain_buffer(prtd, &flags);
2372 if (rc || !atomic_read(&prtd->start)) {
2373 if (rc != -ENETRESET)
2374 rc = -EINTR;
2375 spin_unlock_irqrestore(&prtd->lock, flags);
2376 break;
2377 }
2378 /*
2379 * FIXME: Bug.
2380 * Write(32767)
2381 * Start
2382 * Drain <- Indefinite wait
2383 * sol1 : if (prtd->copied_total) then wait?
2384 * sol2 : (prtd->cmd_interrupt || prtd->drain_ready ||
2385 * atomic_read(xrun)
2386 */
2387 bytes_to_write = prtd->bytes_received
2388 - prtd->copied_total;
2389 WARN(bytes_to_write > runtime->fragment_size,
2390 "last write %d cannot be > than fragment_size",
2391 bytes_to_write);
2392
2393 if (bytes_to_write > 0) {
2394 pr_debug("%s: send %d partial bytes at the end",
2395 __func__, bytes_to_write);
2396 atomic_set(&prtd->xrun, 0);
2397 prtd->last_buffer = 1;
2398 msm_compr_send_buffer(prtd);
2399 }
2400 }
2401
2402 if ((cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN) &&
2403 (prtd->gapless_state.set_next_stream_id)) {
2404 /* wait for the last buffer to be returned */
2405
2406 if (prtd->last_buffer) {
2407 pr_debug("%s: last buffer drain\n", __func__);
2408 rc = msm_compr_drain_buffer(prtd, &flags);
2409 if (rc || !atomic_read(&prtd->start)) {
2410 spin_unlock_irqrestore(&prtd->lock,
2411 flags);
2412 break;
2413 }
2414 }
2415 /* send EOS */
2416 prtd->eos_ack = 0;
2417 atomic_set(&prtd->eos, 1);
2418 pr_debug("issue CMD_EOS stream_id %d\n", ac->stream_id);
2419 q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
2420 pr_info("PARTIAL DRAIN, do not wait for EOS ack\n");
2421
2422 /* send a zero length buffer */
2423 atomic_set(&prtd->xrun, 0);
2424 msm_compr_send_buffer(prtd);
2425
2426 /* wait for the zero length buffer to be returned */
2427 pr_debug("%s: zero length buffer drain\n", __func__);
2428 rc = msm_compr_drain_buffer(prtd, &flags);
2429 if (rc || !atomic_read(&prtd->start)) {
2430 spin_unlock_irqrestore(&prtd->lock, flags);
2431 break;
2432 }
2433
2434 /* sleep for additional duration partial drain */
2435 atomic_set(&prtd->drain, 1);
2436 prtd->drain_ready = 0;
2437 pr_debug("%s, additional sleep: %d\n", __func__,
2438 prtd->partial_drain_delay);
2439 spin_unlock_irqrestore(&prtd->lock, flags);
2440 rc = wait_event_timeout(prtd->drain_wait,
2441 prtd->drain_ready || prtd->cmd_interrupt,
2442 msecs_to_jiffies(prtd->partial_drain_delay));
2443 pr_debug("%s: out of additional wait for low sample rate\n",
2444 __func__);
2445 spin_lock_irqsave(&prtd->lock, flags);
2446 if (prtd->cmd_interrupt) {
2447 pr_debug("%s: additional wait interrupted by flush)\n",
2448 __func__);
2449 rc = -EINTR;
2450 prtd->cmd_interrupt = 0;
2451 spin_unlock_irqrestore(&prtd->lock, flags);
2452 break;
2453 }
2454
2455 /* move to next stream and reset vars */
2456 pr_debug("%s: Moving to next stream in gapless\n",
2457 __func__);
2458 ac->stream_id = NEXT_STREAM_ID(ac->stream_id);
2459 prtd->byte_offset = 0;
2460 prtd->app_pointer = 0;
2461 prtd->first_buffer = 1;
2462 prtd->last_buffer = 0;
2463 /*
2464 * Set gapless transition flag only if EOS hasn't been
2465 * acknowledged already.
2466 */
2467 if (atomic_read(&prtd->eos))
2468 prtd->gapless_state.gapless_transition = 1;
2469 prtd->marker_timestamp = 0;
2470
2471 /*
2472 * Don't reset these as these vars map to
2473 * total_bytes_transferred and total_bytes_available
2474 * directly, only total_bytes_transferred will be
2475 * updated in the next avail() ioctl
2476 * prtd->copied_total = 0;
2477 * prtd->bytes_received = 0;
2478 */
2479 atomic_set(&prtd->drain, 0);
2480 atomic_set(&prtd->xrun, 1);
2481 pr_debug("%s: issue CMD_RUN", __func__);
2482 q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
2483 spin_unlock_irqrestore(&prtd->lock, flags);
2484 break;
2485 }
2486 /*
2487 * moving to next stream failed, so reset the gapless state
2488 * set next stream id for the same session so that the same
2489 * stream can be used for gapless playback
2490 */
2491 prtd->gapless_state.set_next_stream_id = false;
2492 prtd->gapless_state.gapless_transition = 0;
2493 pr_debug("%s:CMD_EOS stream_id %d\n", __func__, ac->stream_id);
2494
2495 prtd->eos_ack = 0;
2496 atomic_set(&prtd->eos, 1);
2497 q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id);
2498
2499 spin_unlock_irqrestore(&prtd->lock, flags);
2500
2501
2502 /* Wait indefinitely for DRAIN. Flush can also signal this*/
2503 rc = wait_event_interruptible(prtd->eos_wait,
2504 (prtd->eos_ack ||
2505 prtd->cmd_interrupt ||
2506 atomic_read(&prtd->error)));
2507
2508 if (rc < 0)
2509 pr_err("%s: EOS wait failed\n", __func__);
2510
2511 pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait for EOS\n",
2512 __func__);
2513
2514 if (prtd->cmd_interrupt)
2515 rc = -EINTR;
2516
2517 if (atomic_read(&prtd->error)) {
2518 pr_err("%s: Got RESET EVENTS notification, return\n",
2519 __func__);
2520 rc = -ENETRESET;
2521 }
2522
2523 /*FIXME : what if a flush comes while PC is here */
2524 if (rc == 0) {
2525 /*
2526 * Failed to open second stream in DSP for gapless
2527 * so prepare the current stream in session
2528 * for gapless playback
2529 */
2530 spin_lock_irqsave(&prtd->lock, flags);
2531 pr_debug("%s:issue CMD_PAUSE stream_id %d",
2532 __func__, ac->stream_id);
2533 q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id);
2534 prtd->cmd_ack = 0;
2535 spin_unlock_irqrestore(&prtd->lock, flags);
2536
2537 /*
2538 * Cache this time as last known time
2539 */
2540 if (pdata->use_legacy_api)
2541 q6asm_get_session_time_legacy(
2542 prtd->audio_client,
2543 &prtd->marker_timestamp);
2544 else
2545 q6asm_get_session_time(prtd->audio_client,
2546 &prtd->marker_timestamp);
2547
2548 spin_lock_irqsave(&prtd->lock, flags);
2549 /*
2550 * Don't reset these as these vars map to
2551 * total_bytes_transferred and total_bytes_available.
2552 * Just total_bytes_transferred will be updated
2553 * in the next avail() ioctl.
2554 * prtd->copied_total = 0;
2555 * prtd->bytes_received = 0;
2556 * do not reset prtd->bytes_sent as well as the same
2557 * session is used for gapless playback
2558 */
2559 prtd->byte_offset = 0;
2560
2561 prtd->app_pointer = 0;
2562 prtd->first_buffer = 1;
2563 prtd->last_buffer = 0;
2564 atomic_set(&prtd->drain, 0);
2565 atomic_set(&prtd->xrun, 1);
2566 spin_unlock_irqrestore(&prtd->lock, flags);
2567
2568 pr_debug("%s:issue CMD_FLUSH ac->stream_id %d",
2569 __func__, ac->stream_id);
2570 q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id);
2571
2572 q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
2573 }
2574 prtd->cmd_interrupt = 0;
2575 break;
2576 case SND_COMPR_TRIGGER_NEXT_TRACK:
2577 if (!prtd->gapless_state.use_dsp_gapless_mode) {
2578 pr_debug("%s: ignore trigger next track\n", __func__);
2579 rc = 0;
2580 break;
2581 }
2582 pr_debug("%s: SND_COMPR_TRIGGER_NEXT_TRACK\n", __func__);
2583 spin_lock_irqsave(&prtd->lock, flags);
2584 rc = 0;
2585 /* next stream in gapless */
2586 stream_id = NEXT_STREAM_ID(ac->stream_id);
2587 /*
2588 * Wait if stream 1 has not completed before honoring next
2589 * track for stream 3. Scenario happens if second clip is
2590 * small and fills in one buffer so next track will be
2591 * called immediately.
2592 */
2593 stream_index = STREAM_ARRAY_INDEX(stream_id);
2594 if (stream_index >= MAX_NUMBER_OF_STREAMS ||
2595 stream_index < 0) {
2596 pr_err("%s: Invalid stream index: %d", __func__,
2597 stream_index);
2598 spin_unlock_irqrestore(&prtd->lock, flags);
2599 rc = -EINVAL;
2600 break;
2601 }
2602
2603 if (prtd->gapless_state.stream_opened[stream_index]) {
2604 if (prtd->gapless_state.gapless_transition) {
2605 rc = msm_compr_wait_for_stream_avail(prtd,
2606 &flags);
2607 } else {
2608 /*
2609 * If session is already opened break out if
2610 * the state is not gapless transition. This
2611 * is when seek happens after the last buffer
2612 * is sent to the driver. Next track would be
2613 * called again after last buffer is sent.
2614 */
2615 pr_debug("next session is in opened state\n");
2616 spin_unlock_irqrestore(&prtd->lock, flags);
2617 break;
2618 }
2619 }
2620 spin_unlock_irqrestore(&prtd->lock, flags);
2621 if (rc < 0) {
2622 /*
2623 * if return type EINTR then reset to zero. Tiny
2624 * compress treats EINTR as error and prevents PARTIAL
2625 * DRAIN. EINTR is not an error. wait for stream avail
2626 * is interrupted by some other command like FLUSH.
2627 */
2628 if (rc == -EINTR) {
2629 pr_debug("%s: EINTR reset rc to 0\n", __func__);
2630 rc = 0;
2631 }
2632 break;
2633 }
2634
2635 if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE)
2636 bits_per_sample = 24;
2637 else if (prtd->codec_param.codec.format ==
2638 SNDRV_PCM_FORMAT_S32_LE)
2639 bits_per_sample = 32;
2640
2641 pr_debug("%s: open_write stream_id %d bits_per_sample %d",
2642 __func__, stream_id, bits_per_sample);
2643 rc = q6asm_stream_open_write_v4(prtd->audio_client,
2644 prtd->codec, bits_per_sample,
2645 stream_id,
2646 prtd->gapless_state.use_dsp_gapless_mode);
2647 if (rc < 0) {
2648 pr_err("%s: Session out open failed for gapless\n",
2649 __func__);
2650 break;
2651 }
2652
2653 spin_lock_irqsave(&prtd->lock, flags);
2654 prtd->gapless_state.stream_opened[stream_index] = 1;
2655 prtd->gapless_state.set_next_stream_id = true;
2656 spin_unlock_irqrestore(&prtd->lock, flags);
2657
2658 rc = msm_compr_send_media_format_block(cstream,
2659 stream_id, false);
2660 if (rc < 0) {
2661 pr_err("%s, failed to send media format block\n",
2662 __func__);
2663 break;
2664 }
2665 msm_compr_send_dec_params(cstream, pdata->dec_params[fe_id],
2666 stream_id);
2667 break;
2668 }
2669
2670 return rc;
2671}
2672
2673static int msm_compr_pointer(struct snd_compr_stream *cstream,
2674 struct snd_compr_tstamp *arg)
2675{
2676 struct snd_compr_runtime *runtime = cstream->runtime;
2677 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
2678 struct msm_compr_audio *prtd = runtime->private_data;
2679 struct msm_compr_pdata *pdata = NULL;
2680 struct snd_compr_tstamp tstamp;
2681 uint64_t timestamp = 0;
2682 int rc = 0, first_buffer;
2683 unsigned long flags;
2684 uint32_t gapless_transition;
2685
2686 pdata = snd_soc_platform_get_drvdata(rtd->platform);
2687 pr_debug("%s\n", __func__);
2688 memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp));
2689
2690 spin_lock_irqsave(&prtd->lock, flags);
2691 tstamp.sampling_rate = prtd->sample_rate;
2692 tstamp.byte_offset = prtd->byte_offset;
2693 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2694 tstamp.copied_total = prtd->copied_total;
2695 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2696 tstamp.copied_total = prtd->received_total;
2697 first_buffer = prtd->first_buffer;
2698 if (atomic_read(&prtd->error)) {
Vatsal Bucha0527c562017-10-04 20:38:49 +05302699 pr_err_ratelimited("%s Got RESET EVENTS notification, return error\n",
2700 __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05302701 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2702 runtime->total_bytes_transferred = tstamp.copied_total;
2703 else
2704 runtime->total_bytes_available = tstamp.copied_total;
2705 tstamp.pcm_io_frames = 0;
2706 memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
2707 spin_unlock_irqrestore(&prtd->lock, flags);
2708 return -ENETRESET;
2709 }
2710 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
2711
2712 gapless_transition = prtd->gapless_state.gapless_transition;
2713 spin_unlock_irqrestore(&prtd->lock, flags);
2714 if (gapless_transition)
2715 pr_debug("%s session time in gapless transition",
2716 __func__);
2717 /*
2718 *- Do not query if no buffer has been given.
2719 *- Do not query on a gapless transition.
2720 * Playback for the 2nd stream can start (thus returning time
2721 * starting from 0) before the driver knows about EOS of first
2722 * stream.
2723 */
2724 if (!first_buffer || gapless_transition) {
2725
2726 if (pdata->use_legacy_api)
2727 rc = q6asm_get_session_time_legacy(
2728 prtd->audio_client, &prtd->marker_timestamp);
2729 else
2730 rc = q6asm_get_session_time(
2731 prtd->audio_client, &prtd->marker_timestamp);
2732 if (rc < 0) {
2733 pr_err("%s: Get Session Time return =%lld\n",
2734 __func__, timestamp);
2735 if (atomic_read(&prtd->error))
2736 return -ENETRESET;
2737 else
2738 return -EAGAIN;
2739 }
2740 }
2741 } else {
2742 spin_unlock_irqrestore(&prtd->lock, flags);
2743 }
2744 timestamp = prtd->marker_timestamp;
2745
2746 /* DSP returns timestamp in usec */
2747 pr_debug("%s: timestamp = %lld usec\n", __func__, timestamp);
2748 timestamp *= prtd->sample_rate;
2749 tstamp.pcm_io_frames = (snd_pcm_uframes_t)div64_u64(timestamp, 1000000);
2750 memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
2751
2752 return 0;
2753}
2754
2755static int msm_compr_ack(struct snd_compr_stream *cstream,
2756 size_t count)
2757{
2758 struct snd_compr_runtime *runtime = cstream->runtime;
2759 struct msm_compr_audio *prtd = runtime->private_data;
2760 void *src, *dstn;
2761 size_t copy;
2762 unsigned long flags;
2763
2764 WARN(1, "This path is untested");
2765 return -EINVAL;
2766
2767 pr_debug("%s: count = %zd\n", __func__, count);
2768 if (!prtd->buffer) {
2769 pr_err("%s: Buffer is not allocated yet ??\n", __func__);
2770 return -EINVAL;
2771 }
2772 src = runtime->buffer + prtd->app_pointer;
2773 dstn = prtd->buffer + prtd->app_pointer;
2774 if (count < prtd->buffer_size - prtd->app_pointer) {
2775 memcpy(dstn, src, count);
2776 prtd->app_pointer += count;
2777 } else {
2778 copy = prtd->buffer_size - prtd->app_pointer;
2779 memcpy(dstn, src, copy);
2780 memcpy(prtd->buffer, runtime->buffer, count - copy);
2781 prtd->app_pointer = count - copy;
2782 }
2783
2784 /*
2785 * If the stream is started and all the bytes received were
2786 * copied to DSP, the newly received bytes should be
2787 * sent right away
2788 */
2789 spin_lock_irqsave(&prtd->lock, flags);
2790
2791 if (atomic_read(&prtd->start) &&
2792 prtd->bytes_received == prtd->copied_total) {
2793 prtd->bytes_received += count;
2794 msm_compr_send_buffer(prtd);
2795 } else
2796 prtd->bytes_received += count;
2797
2798 spin_unlock_irqrestore(&prtd->lock, flags);
2799
2800 return 0;
2801}
2802
2803static int msm_compr_playback_copy(struct snd_compr_stream *cstream,
2804 char __user *buf, size_t count)
2805{
2806 struct snd_compr_runtime *runtime = cstream->runtime;
2807 struct msm_compr_audio *prtd = runtime->private_data;
2808 void *dstn;
2809 size_t copy;
2810 uint64_t bytes_available = 0;
2811 unsigned long flags;
2812
2813 pr_debug("%s: count = %zd\n", __func__, count);
2814 if (!prtd->buffer) {
2815 pr_err("%s: Buffer is not allocated yet ??", __func__);
2816 return 0;
2817 }
2818
2819 spin_lock_irqsave(&prtd->lock, flags);
2820 if (atomic_read(&prtd->error)) {
2821 pr_err("%s Got RESET EVENTS notification", __func__);
2822 spin_unlock_irqrestore(&prtd->lock, flags);
2823 return -ENETRESET;
2824 }
2825 spin_unlock_irqrestore(&prtd->lock, flags);
2826
2827 dstn = prtd->buffer + prtd->app_pointer;
2828 if (count < prtd->buffer_size - prtd->app_pointer) {
2829 if (copy_from_user(dstn, buf, count))
2830 return -EFAULT;
2831 prtd->app_pointer += count;
2832 } else {
2833 copy = prtd->buffer_size - prtd->app_pointer;
2834 if (copy_from_user(dstn, buf, copy))
2835 return -EFAULT;
2836 if (copy_from_user(prtd->buffer, buf + copy, count - copy))
2837 return -EFAULT;
2838 prtd->app_pointer = count - copy;
2839 }
2840
2841 /*
2842 * If stream is started and there has been an xrun,
2843 * since the available bytes fits fragment_size, copy the data
2844 * right away.
2845 */
2846 spin_lock_irqsave(&prtd->lock, flags);
2847 prtd->bytes_received += count;
2848 if (atomic_read(&prtd->start)) {
2849 if (atomic_read(&prtd->xrun)) {
2850 pr_debug("%s: in xrun, count = %zd\n", __func__, count);
2851 bytes_available = prtd->bytes_received -
2852 prtd->copied_total;
2853 if (bytes_available >= runtime->fragment_size) {
2854 pr_debug("%s: handle xrun, bytes_to_write = %llu\n",
2855 __func__, bytes_available);
2856 atomic_set(&prtd->xrun, 0);
2857 msm_compr_send_buffer(prtd);
2858 } /* else not sufficient data */
2859 } /* writes will continue on the next write_done */
2860 }
2861
2862 spin_unlock_irqrestore(&prtd->lock, flags);
2863
2864 return count;
2865}
2866
2867static int msm_compr_capture_copy(struct snd_compr_stream *cstream,
2868 char __user *buf, size_t count)
2869{
2870 struct snd_compr_runtime *runtime = cstream->runtime;
2871 struct msm_compr_audio *prtd = runtime->private_data;
2872 void *source;
2873 unsigned long flags;
2874
2875 pr_debug("%s: count = %zd\n", __func__, count);
2876 if (!prtd->buffer) {
2877 pr_err("%s: Buffer is not allocated yet ??", __func__);
2878 return 0;
2879 }
2880
2881 spin_lock_irqsave(&prtd->lock, flags);
2882 if (atomic_read(&prtd->error)) {
2883 pr_err("%s Got RESET EVENTS notification", __func__);
2884 spin_unlock_irqrestore(&prtd->lock, flags);
2885 return -ENETRESET;
2886 }
2887
2888 source = prtd->buffer + prtd->app_pointer;
2889 /* check if we have requested amount of data to copy to user*/
2890 if (count <= prtd->received_total - prtd->bytes_copied) {
2891 spin_unlock_irqrestore(&prtd->lock, flags);
2892 if (copy_to_user(buf, source, count)) {
2893 pr_err("copy_to_user failed");
2894 return -EFAULT;
2895 }
2896 spin_lock_irqsave(&prtd->lock, flags);
2897 prtd->app_pointer += count;
2898 if (prtd->app_pointer >= prtd->buffer_size)
2899 prtd->app_pointer -= prtd->buffer_size;
2900 prtd->bytes_copied += count;
2901 }
2902 msm_compr_read_buffer(prtd);
2903
2904 spin_unlock_irqrestore(&prtd->lock, flags);
2905 return count;
2906}
2907
2908static int msm_compr_copy(struct snd_compr_stream *cstream,
2909 char __user *buf, size_t count)
2910{
2911 int ret = 0;
2912
2913 pr_debug(" In %s\n", __func__);
2914 if (cstream->direction == SND_COMPRESS_PLAYBACK)
2915 ret = msm_compr_playback_copy(cstream, buf, count);
2916 else if (cstream->direction == SND_COMPRESS_CAPTURE)
2917 ret = msm_compr_capture_copy(cstream, buf, count);
2918 return ret;
2919}
2920
2921static int msm_compr_get_caps(struct snd_compr_stream *cstream,
2922 struct snd_compr_caps *arg)
2923{
2924 struct snd_compr_runtime *runtime = cstream->runtime;
2925 struct msm_compr_audio *prtd = runtime->private_data;
2926 int ret = 0;
2927
2928 pr_debug("%s\n", __func__);
2929 if ((arg != NULL) && (prtd != NULL)) {
2930 memcpy(arg, &prtd->compr_cap, sizeof(struct snd_compr_caps));
2931 } else {
2932 ret = -EINVAL;
2933 pr_err("%s: arg (0x%pK), prtd (0x%pK)\n", __func__, arg, prtd);
2934 }
2935
2936 return ret;
2937}
2938
2939static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
2940 struct snd_compr_codec_caps *codec)
2941{
2942 pr_debug("%s\n", __func__);
2943
2944 switch (codec->codec) {
2945 case SND_AUDIOCODEC_MP3:
2946 codec->num_descriptors = 2;
2947 codec->descriptor[0].max_ch = 2;
2948 memcpy(codec->descriptor[0].sample_rates,
2949 supported_sample_rates,
2950 sizeof(supported_sample_rates));
2951 codec->descriptor[0].num_sample_rates =
2952 sizeof(supported_sample_rates)/sizeof(unsigned int);
2953 codec->descriptor[0].bit_rate[0] = 320; /* 320kbps */
2954 codec->descriptor[0].bit_rate[1] = 128;
2955 codec->descriptor[0].num_bitrates = 2;
2956 codec->descriptor[0].profiles = 0;
2957 codec->descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO;
2958 codec->descriptor[0].formats = 0;
2959 break;
2960 case SND_AUDIOCODEC_AAC:
2961 codec->num_descriptors = 2;
2962 codec->descriptor[1].max_ch = 2;
2963 memcpy(codec->descriptor[1].sample_rates,
2964 supported_sample_rates,
2965 sizeof(supported_sample_rates));
2966 codec->descriptor[1].num_sample_rates =
2967 sizeof(supported_sample_rates)/sizeof(unsigned int);
2968 codec->descriptor[1].bit_rate[0] = 320; /* 320kbps */
2969 codec->descriptor[1].bit_rate[1] = 128;
2970 codec->descriptor[1].num_bitrates = 2;
2971 codec->descriptor[1].profiles = 0;
2972 codec->descriptor[1].modes = 0;
2973 codec->descriptor[1].formats =
2974 (SND_AUDIOSTREAMFORMAT_MP4ADTS |
2975 SND_AUDIOSTREAMFORMAT_RAW);
2976 break;
2977 case SND_AUDIOCODEC_AC3:
2978 case SND_AUDIOCODEC_EAC3:
2979 case SND_AUDIOCODEC_FLAC:
2980 case SND_AUDIOCODEC_VORBIS:
2981 case SND_AUDIOCODEC_ALAC:
2982 case SND_AUDIOCODEC_APE:
2983 case SND_AUDIOCODEC_DTS:
2984 case SND_AUDIOCODEC_DSD:
2985 case SND_AUDIOCODEC_TRUEHD:
2986 case SND_AUDIOCODEC_IEC61937:
2987 case SND_AUDIOCODEC_APTX:
2988 break;
2989 default:
2990 pr_err("%s: Unsupported audio codec %d\n",
2991 __func__, codec->codec);
2992 return -EINVAL;
2993 }
2994
2995 return 0;
2996}
2997
2998static int msm_compr_set_metadata(struct snd_compr_stream *cstream,
2999 struct snd_compr_metadata *metadata)
3000{
3001 struct msm_compr_audio *prtd;
3002 struct audio_client *ac;
3003 pr_debug("%s\n", __func__);
3004
3005 if (!metadata || !cstream)
3006 return -EINVAL;
3007
3008 prtd = cstream->runtime->private_data;
3009 if (!prtd || !prtd->audio_client) {
3010 pr_err("%s: prtd or audio client is NULL\n", __func__);
3011 return -EINVAL;
3012 }
3013
3014 if (((metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) ||
3015 (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY)) &&
3016 (prtd->compr_passthr != LEGACY_PCM)) {
3017 pr_debug("%s: No trailing silence for compress_type[%d]\n",
3018 __func__, prtd->compr_passthr);
3019 return 0;
3020 }
3021
3022 ac = prtd->audio_client;
3023 if (metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) {
3024 pr_debug("%s, got encoder padding %u",
3025 __func__, metadata->value[0]);
3026 prtd->gapless_state.trailing_samples_drop = metadata->value[0];
3027 } else if (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY) {
3028 pr_debug("%s, got encoder delay %u",
3029 __func__, metadata->value[0]);
3030 prtd->gapless_state.initial_samples_drop = metadata->value[0];
3031 } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) {
3032 return msm_compr_set_render_mode(prtd, metadata->value[0]);
3033 } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) {
3034 return msm_compr_set_clk_rec_mode(ac, metadata->value[0]);
3035 } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) {
3036 return msm_compr_set_render_window(
3037 ac,
3038 metadata->value[0],
3039 metadata->value[1],
3040 metadata->value[2],
3041 metadata->value[3]);
3042 } else if (metadata->key == SNDRV_COMPRESS_START_DELAY) {
3043 prtd->start_delay_lsw = metadata->value[0];
3044 prtd->start_delay_msw = metadata->value[1];
3045 } else if (metadata->key ==
3046 SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK) {
3047 return msm_compr_enable_adjust_session_clock(ac,
3048 metadata->value[0]);
3049 } else if (metadata->key == SNDRV_COMPRESS_ADJUST_SESSION_CLOCK) {
3050 return msm_compr_adjust_session_clock(ac,
3051 metadata->value[0],
3052 metadata->value[1]);
3053 }
3054
3055 return 0;
3056}
3057
3058static int msm_compr_get_metadata(struct snd_compr_stream *cstream,
3059 struct snd_compr_metadata *metadata)
3060{
3061 struct msm_compr_audio *prtd;
3062 struct audio_client *ac;
3063 int ret = -EINVAL;
3064
3065 pr_debug("%s\n", __func__);
3066
3067 if (!metadata || !cstream || !cstream->runtime)
3068 return ret;
3069
3070 if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) {
3071 pr_err("%s, unsupported key %d\n", __func__, metadata->key);
3072 return ret;
3073 }
3074
3075 prtd = cstream->runtime->private_data;
3076 if (!prtd || !prtd->audio_client) {
3077 pr_err("%s: prtd or audio client is NULL\n", __func__);
3078 return ret;
3079 }
3080
3081 ac = prtd->audio_client;
3082 ret = q6asm_get_path_delay(prtd->audio_client);
3083 if (ret) {
3084 pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret);
3085 return ret;
3086 }
3087
3088 pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay);
3089
3090 metadata->value[0] = ac->path_delay;
3091
3092 return ret;
3093}
3094
3095
3096static int msm_compr_set_next_track_param(struct snd_compr_stream *cstream,
3097 union snd_codec_options *codec_options)
3098{
3099 struct msm_compr_audio *prtd;
3100 struct audio_client *ac;
3101 int ret = 0;
3102
3103 if (!codec_options || !cstream)
3104 return -EINVAL;
3105
3106 prtd = cstream->runtime->private_data;
3107 if (!prtd || !prtd->audio_client) {
3108 pr_err("%s: prtd or audio client is NULL\n", __func__);
3109 return -EINVAL;
3110 }
3111
3112 ac = prtd->audio_client;
3113
3114 pr_debug("%s: got codec options for codec type %u",
3115 __func__, prtd->codec);
3116 switch (prtd->codec) {
3117 case FORMAT_WMA_V9:
3118 case FORMAT_WMA_V10PRO:
3119 case FORMAT_FLAC:
3120 case FORMAT_VORBIS:
3121 case FORMAT_ALAC:
3122 case FORMAT_APE:
3123 memcpy(&(prtd->gapless_state.codec_options),
3124 codec_options,
3125 sizeof(union snd_codec_options));
3126 ret = msm_compr_send_media_format_block(cstream,
3127 ac->stream_id, true);
3128 if (ret < 0) {
3129 pr_err("%s: failed to send media format block\n",
3130 __func__);
3131 }
3132 break;
3133
3134 default:
3135 pr_debug("%s: Ignore sending CMD Format block\n",
3136 __func__);
3137 break;
3138 }
3139
3140 return ret;
3141}
3142
3143static int msm_compr_volume_put(struct snd_kcontrol *kcontrol,
3144 struct snd_ctl_elem_value *ucontrol)
3145{
3146 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3147 unsigned long fe_id = kcontrol->private_value;
3148 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3149 snd_soc_component_get_drvdata(comp);
3150 struct snd_compr_stream *cstream = NULL;
3151 uint32_t *volume = NULL;
3152
3153 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3154 pr_err("%s Received out of bounds fe_id %lu\n",
3155 __func__, fe_id);
3156 return -EINVAL;
3157 }
3158
3159 cstream = pdata->cstream[fe_id];
3160 volume = pdata->volume[fe_id];
3161
3162 volume[0] = ucontrol->value.integer.value[0];
3163 volume[1] = ucontrol->value.integer.value[1];
3164 pr_debug("%s: fe_id %lu left_vol %d right_vol %d\n",
3165 __func__, fe_id, volume[0], volume[1]);
3166 if (cstream)
3167 msm_compr_set_volume(cstream, volume[0], volume[1]);
3168 return 0;
3169}
3170
3171static int msm_compr_volume_get(struct snd_kcontrol *kcontrol,
3172 struct snd_ctl_elem_value *ucontrol)
3173{
3174 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3175 unsigned long fe_id = kcontrol->private_value;
3176
3177 struct msm_compr_pdata *pdata =
3178 snd_soc_component_get_drvdata(comp);
3179 uint32_t *volume = NULL;
3180
3181 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3182 pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id);
3183 return -EINVAL;
3184 }
3185
3186 volume = pdata->volume[fe_id];
3187 pr_debug("%s: fe_id %lu\n", __func__, fe_id);
3188 ucontrol->value.integer.value[0] = volume[0];
3189 ucontrol->value.integer.value[1] = volume[1];
3190
3191 return 0;
3192}
3193
3194static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
3195 struct snd_ctl_elem_value *ucontrol)
3196{
3197 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3198 unsigned long fe_id = kcontrol->private_value;
3199 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3200 snd_soc_component_get_drvdata(comp);
3201 struct msm_compr_audio_effects *audio_effects = NULL;
3202 struct snd_compr_stream *cstream = NULL;
3203 struct msm_compr_audio *prtd = NULL;
3204 long *values = &(ucontrol->value.integer.value[0]);
3205 int effects_module;
3206
3207 pr_debug("%s\n", __func__);
3208 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3209 pr_err("%s Received out of bounds fe_id %lu\n",
3210 __func__, fe_id);
3211 return -EINVAL;
3212 }
3213 cstream = pdata->cstream[fe_id];
3214 audio_effects = pdata->audio_effects[fe_id];
3215 if (!cstream || !audio_effects) {
3216 pr_err("%s: stream or effects inactive\n", __func__);
3217 return -EINVAL;
3218 }
3219 prtd = cstream->runtime->private_data;
3220 if (!prtd) {
3221 pr_err("%s: cannot set audio effects\n", __func__);
3222 return -EINVAL;
3223 }
3224 if (prtd->compr_passthr != LEGACY_PCM) {
3225 pr_debug("%s: No effects for compr_type[%d]\n",
3226 __func__, prtd->compr_passthr);
3227 return 0;
3228 }
3229 pr_debug("%s: Effects supported for compr_type[%d]\n",
3230 __func__, prtd->compr_passthr);
3231
3232 effects_module = *values++;
3233 switch (effects_module) {
3234 case VIRTUALIZER_MODULE:
3235 pr_debug("%s: VIRTUALIZER_MODULE\n", __func__);
3236 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3237 prtd->audio_client->topology))
3238 msm_audio_effects_virtualizer_handler(
3239 prtd->audio_client,
3240 &(audio_effects->virtualizer),
3241 values);
3242 break;
3243 case REVERB_MODULE:
3244 pr_debug("%s: REVERB_MODULE\n", __func__);
3245 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3246 prtd->audio_client->topology))
3247 msm_audio_effects_reverb_handler(prtd->audio_client,
3248 &(audio_effects->reverb),
3249 values);
3250 break;
3251 case BASS_BOOST_MODULE:
3252 pr_debug("%s: BASS_BOOST_MODULE\n", __func__);
3253 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3254 prtd->audio_client->topology))
3255 msm_audio_effects_bass_boost_handler(prtd->audio_client,
3256 &(audio_effects->bass_boost),
3257 values);
3258 break;
3259 case PBE_MODULE:
3260 pr_debug("%s: PBE_MODULE\n", __func__);
3261 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3262 prtd->audio_client->topology))
3263 msm_audio_effects_pbe_handler(prtd->audio_client,
3264 &(audio_effects->pbe),
3265 values);
3266 break;
3267 case EQ_MODULE:
3268 pr_debug("%s: EQ_MODULE\n", __func__);
3269 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3270 prtd->audio_client->topology))
3271 msm_audio_effects_popless_eq_handler(prtd->audio_client,
3272 &(audio_effects->equalizer),
3273 values);
3274 break;
3275 case SOFT_VOLUME_MODULE:
3276 pr_debug("%s: SOFT_VOLUME_MODULE\n", __func__);
3277 break;
3278 case SOFT_VOLUME2_MODULE:
3279 pr_debug("%s: SOFT_VOLUME2_MODULE\n", __func__);
3280 if (msm_audio_effects_is_effmodule_supp_in_top(effects_module,
3281 prtd->audio_client->topology))
3282 msm_audio_effects_volume_handler_v2(prtd->audio_client,
3283 &(audio_effects->volume),
3284 values, SOFT_VOLUME_INSTANCE_2);
3285 break;
3286 default:
3287 pr_err("%s Invalid effects config module\n", __func__);
3288 return -EINVAL;
3289 }
3290 return 0;
3291}
3292
3293static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
3294 struct snd_ctl_elem_value *ucontrol)
3295{
3296 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3297 unsigned long fe_id = kcontrol->private_value;
3298 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3299 snd_soc_component_get_drvdata(comp);
3300 struct msm_compr_audio_effects *audio_effects = NULL;
3301 struct snd_compr_stream *cstream = NULL;
3302 struct msm_compr_audio *prtd = NULL;
3303
3304 pr_debug("%s\n", __func__);
3305 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3306 pr_err("%s Received out of bounds fe_id %lu\n",
3307 __func__, fe_id);
3308 return -EINVAL;
3309 }
3310 cstream = pdata->cstream[fe_id];
3311 audio_effects = pdata->audio_effects[fe_id];
3312 if (!cstream || !audio_effects) {
Vignesh Kulothungan2ce67842018-09-25 16:40:29 -07003313 pr_debug("%s: stream or effects inactive\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303314 return -EINVAL;
3315 }
3316 prtd = cstream->runtime->private_data;
3317 if (!prtd) {
3318 pr_err("%s: cannot set audio effects\n", __func__);
3319 return -EINVAL;
3320 }
3321
3322 return 0;
3323}
3324
3325static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
3326 struct snd_ctl_elem_value *ucontrol)
3327{
3328 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3329 unsigned long fe_id = kcontrol->private_value;
3330 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3331 snd_soc_component_get_drvdata(comp);
3332 struct msm_compr_audio_effects *audio_effects = NULL;
3333 struct snd_compr_stream *cstream = NULL;
3334 struct msm_compr_audio *prtd = NULL;
3335 long *values = &(ucontrol->value.integer.value[0]);
3336
3337 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3338 pr_err("%s Received out of bounds fe_id %lu\n",
3339 __func__, fe_id);
3340 return -EINVAL;
3341 }
3342 cstream = pdata->cstream[fe_id];
3343 audio_effects = pdata->audio_effects[fe_id];
3344 if (!cstream || !audio_effects) {
3345 pr_err("%s: stream or effects inactive\n", __func__);
3346 return -EINVAL;
3347 }
3348 prtd = cstream->runtime->private_data;
3349 if (!prtd) {
3350 pr_err("%s: cannot set audio effects\n", __func__);
3351 return -EINVAL;
3352 }
3353 if (prtd->compr_passthr != LEGACY_PCM) {
3354 pr_err("%s: No effects for compr_type[%d]\n",
3355 __func__, prtd->compr_passthr);
3356 return -EPERM;
3357 }
3358 audio_effects->query.mod_id = (u32)*values++;
3359 audio_effects->query.parm_id = (u32)*values++;
3360 audio_effects->query.size = (u32)*values++;
3361 audio_effects->query.offset = (u32)*values++;
3362 audio_effects->query.device = (u32)*values++;
3363 return 0;
3364}
3365
3366static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
3367 struct snd_ctl_elem_value *ucontrol)
3368{
3369 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3370 unsigned long fe_id = kcontrol->private_value;
3371 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3372 snd_soc_component_get_drvdata(comp);
3373 struct msm_compr_audio_effects *audio_effects = NULL;
3374 struct snd_compr_stream *cstream = NULL;
3375 struct msm_compr_audio *prtd = NULL;
3376 long *values = &(ucontrol->value.integer.value[0]);
3377
3378 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3379 pr_err("%s Received out of bounds fe_id %lu\n",
3380 __func__, fe_id);
3381 return -EINVAL;
3382 }
3383 cstream = pdata->cstream[fe_id];
3384 audio_effects = pdata->audio_effects[fe_id];
3385 if (!cstream || !audio_effects) {
3386 pr_debug("%s: stream or effects inactive\n", __func__);
3387 return -EINVAL;
3388 }
3389 prtd = cstream->runtime->private_data;
3390 if (!prtd) {
3391 pr_err("%s: cannot set audio effects\n", __func__);
3392 return -EINVAL;
3393 }
3394 values[0] = (long)audio_effects->query.mod_id;
3395 values[1] = (long)audio_effects->query.parm_id;
3396 values[2] = (long)audio_effects->query.size;
3397 values[3] = (long)audio_effects->query.offset;
3398 values[4] = (long)audio_effects->query.device;
3399 return 0;
3400}
3401
3402static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
3403 struct msm_compr_dec_params *dec_params,
3404 int stream_id)
3405{
3406
3407 int rc = 0;
3408 struct msm_compr_audio *prtd = NULL;
3409 struct snd_dec_ddp *ddp = &dec_params->ddp_params;
3410
3411 if (!cstream || !dec_params) {
3412 pr_err("%s: stream or dec_params inactive\n", __func__);
3413 rc = -EINVAL;
3414 goto end;
3415 }
3416 prtd = cstream->runtime->private_data;
3417 if (!prtd) {
3418 pr_err("%s: cannot set dec_params\n", __func__);
3419 rc = -EINVAL;
3420 goto end;
3421 }
3422 switch (prtd->codec) {
3423 case FORMAT_MP3:
3424 case FORMAT_MPEG4_AAC:
3425 case FORMAT_TRUEHD:
3426 case FORMAT_IEC61937:
3427 case FORMAT_APTX:
3428 pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
3429 prtd->codec);
3430 break;
3431 case FORMAT_AC3:
3432 case FORMAT_EAC3:
3433 if (prtd->compr_passthr != LEGACY_PCM) {
3434 pr_debug("%s: No DDP param for compr_type[%d]\n",
3435 __func__, prtd->compr_passthr);
3436 break;
3437 }
3438 rc = msm_compr_send_ddp_cfg(prtd->audio_client, ddp, stream_id);
3439 if (rc < 0)
3440 pr_err("%s: DDP CMD CFG failed %d\n", __func__, rc);
3441 break;
3442 default:
3443 break;
3444 }
3445end:
3446 return rc;
3447
3448}
3449static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
3450 struct snd_ctl_elem_value *ucontrol)
3451{
3452 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3453 unsigned long fe_id = kcontrol->private_value;
3454 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3455 snd_soc_component_get_drvdata(comp);
3456 struct msm_compr_dec_params *dec_params = NULL;
3457 struct snd_compr_stream *cstream = NULL;
3458 struct msm_compr_audio *prtd = NULL;
3459 long *values = &(ucontrol->value.integer.value[0]);
3460 int rc = 0;
3461
3462 pr_debug("%s\n", __func__);
3463 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3464 pr_err("%s Received out of bounds fe_id %lu\n",
3465 __func__, fe_id);
3466 rc = -EINVAL;
3467 goto end;
3468 }
3469
3470 cstream = pdata->cstream[fe_id];
3471 dec_params = pdata->dec_params[fe_id];
3472
3473 if (!cstream || !dec_params) {
3474 pr_err("%s: stream or dec_params inactive\n", __func__);
3475 rc = -EINVAL;
3476 goto end;
3477 }
3478 prtd = cstream->runtime->private_data;
3479 if (!prtd) {
3480 pr_err("%s: cannot set dec_params\n", __func__);
3481 rc = -EINVAL;
3482 goto end;
3483 }
3484
3485 switch (prtd->codec) {
3486 case FORMAT_MP3:
3487 case FORMAT_MPEG4_AAC:
3488 case FORMAT_FLAC:
3489 case FORMAT_VORBIS:
3490 case FORMAT_ALAC:
3491 case FORMAT_APE:
3492 case FORMAT_DTS:
3493 case FORMAT_DSD:
3494 case FORMAT_TRUEHD:
3495 case FORMAT_IEC61937:
3496 case FORMAT_APTX:
3497 pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
3498 prtd->codec);
3499 break;
3500 case FORMAT_AC3:
3501 case FORMAT_EAC3: {
3502 struct snd_dec_ddp *ddp = &dec_params->ddp_params;
3503 int cnt;
3504
3505 if (prtd->compr_passthr != LEGACY_PCM) {
3506 pr_debug("%s: No DDP param for compr_type[%d]\n",
3507 __func__, prtd->compr_passthr);
3508 break;
3509 }
3510
3511 ddp->params_length = (*values++);
3512 if (ddp->params_length > DDP_DEC_MAX_NUM_PARAM) {
3513 pr_err("%s: invalid num of params:: %d\n", __func__,
3514 ddp->params_length);
3515 rc = -EINVAL;
3516 goto end;
3517 }
3518 for (cnt = 0; cnt < ddp->params_length; cnt++) {
3519 ddp->params_id[cnt] = *values++;
3520 ddp->params_value[cnt] = *values++;
3521 }
3522 prtd = cstream->runtime->private_data;
3523 if (prtd && prtd->audio_client)
3524 rc = msm_compr_send_dec_params(cstream, dec_params,
3525 prtd->audio_client->stream_id);
3526 break;
3527 }
3528 default:
3529 break;
3530 }
3531end:
3532 pr_debug("%s: ret %d\n", __func__, rc);
3533 return rc;
3534}
3535
3536static int msm_compr_dec_params_get(struct snd_kcontrol *kcontrol,
3537 struct snd_ctl_elem_value *ucontrol)
3538{
3539 /* dummy function */
3540 return 0;
3541}
3542
3543static int msm_compr_playback_app_type_cfg_put(struct snd_kcontrol *kcontrol,
3544 struct snd_ctl_elem_value *ucontrol)
3545{
3546 u64 fe_id = kcontrol->private_value;
3547 int session_type = SESSION_TYPE_RX;
3548 int be_id = ucontrol->value.integer.value[3];
3549 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
3550 int ret = 0;
3551
3552 cfg_data.app_type = ucontrol->value.integer.value[0];
3553 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
3554 if (ucontrol->value.integer.value[2] != 0)
3555 cfg_data.sample_rate = ucontrol->value.integer.value[2];
3556 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n",
3557 __func__, fe_id, session_type, be_id,
3558 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3559 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
3560 be_id, &cfg_data);
3561 if (ret < 0)
3562 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
3563 __func__, ret);
3564
3565 return ret;
3566}
3567
3568static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol,
3569 struct snd_ctl_elem_value *ucontrol)
3570{
3571 u64 fe_id = kcontrol->private_value;
3572 int session_type = SESSION_TYPE_RX;
3573 int be_id = 0;
3574 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
3575 int ret = 0;
3576
3577 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
3578 &be_id, &cfg_data);
3579 if (ret < 0) {
3580 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
3581 __func__, ret);
3582 goto done;
3583 }
3584
3585 ucontrol->value.integer.value[0] = cfg_data.app_type;
3586 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
3587 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
3588 ucontrol->value.integer.value[3] = be_id;
3589 pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
3590 __func__, fe_id, session_type, be_id,
3591 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3592done:
3593 return ret;
3594}
3595
3596static int msm_compr_capture_app_type_cfg_put(struct snd_kcontrol *kcontrol,
3597 struct snd_ctl_elem_value *ucontrol)
3598{
3599 u64 fe_id = kcontrol->private_value;
3600 int session_type = SESSION_TYPE_TX;
3601 int be_id = ucontrol->value.integer.value[3];
3602 struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
3603 int ret = 0;
3604
3605 cfg_data.app_type = ucontrol->value.integer.value[0];
3606 cfg_data.acdb_dev_id = ucontrol->value.integer.value[1];
3607 if (ucontrol->value.integer.value[2] != 0)
3608 cfg_data.sample_rate = ucontrol->value.integer.value[2];
3609 pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n",
3610 __func__, fe_id, session_type, be_id,
3611 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3612 ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
3613 be_id, &cfg_data);
3614 if (ret < 0)
3615 pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n",
3616 __func__, ret);
3617
3618 return ret;
3619}
3620
3621static int msm_compr_capture_app_type_cfg_get(struct snd_kcontrol *kcontrol,
3622 struct snd_ctl_elem_value *ucontrol)
3623{
3624 u64 fe_id = kcontrol->private_value;
3625 int session_type = SESSION_TYPE_TX;
3626 int be_id = 0;
3627 struct msm_pcm_stream_app_type_cfg cfg_data = {0};
3628 int ret = 0;
3629
3630 ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
3631 &be_id, &cfg_data);
3632 if (ret < 0) {
3633 pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
3634 __func__, ret);
3635 goto done;
3636 }
3637
3638 ucontrol->value.integer.value[0] = cfg_data.app_type;
3639 ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id;
3640 ucontrol->value.integer.value[2] = cfg_data.sample_rate;
3641 ucontrol->value.integer.value[3] = be_id;
3642 pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
3643 __func__, fe_id, session_type, be_id,
3644 cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
3645done:
3646 return ret;
3647}
3648
3649static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol,
3650 struct snd_ctl_elem_value *ucontrol)
3651{
3652 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3653 u64 fe_id = kcontrol->private_value;
3654 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3655 snd_soc_component_get_drvdata(comp);
3656 int rc = 0, i;
3657
3658 pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
3659
3660 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3661 pr_err("%s Received out of bounds fe_id %llu\n",
3662 __func__, fe_id);
3663 rc = -EINVAL;
3664 goto end;
3665 }
3666
3667 if (pdata->ch_map[fe_id]) {
3668 pdata->ch_map[fe_id]->set_ch_map = true;
Dieter Lueckingceef9af2018-09-28 15:09:32 +02003669 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303670 pdata->ch_map[fe_id]->channel_map[i] =
3671 (char)(ucontrol->value.integer.value[i]);
3672 } else {
3673 pr_debug("%s: no memory for ch_map, default will be set\n",
3674 __func__);
3675 }
3676end:
3677 pr_debug("%s: ret %d\n", __func__, rc);
3678 return rc;
3679}
3680
3681static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol,
3682 struct snd_ctl_elem_value *ucontrol)
3683{
3684 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3685 u64 fe_id = kcontrol->private_value;
3686 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3687 snd_soc_component_get_drvdata(comp);
3688 int rc = 0, i;
3689
3690 pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
3691 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3692 pr_err("%s: Received out of bounds fe_id %llu\n",
3693 __func__, fe_id);
3694 rc = -EINVAL;
3695 goto end;
3696 }
3697 if (pdata->ch_map[fe_id]) {
Dieter Lueckingceef9af2018-09-28 15:09:32 +02003698 for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303699 ucontrol->value.integer.value[i] =
3700 pdata->ch_map[fe_id]->channel_map[i];
3701 }
3702end:
3703 pr_debug("%s: ret %d\n", __func__, rc);
3704 return rc;
3705}
3706
3707static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
3708 struct snd_ctl_elem_value *ucontrol)
3709{
3710 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3711 unsigned long fe_id = kcontrol->private_value;
3712 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3713 snd_soc_component_get_drvdata(comp);
3714 struct snd_compr_stream *cstream = NULL;
3715 struct msm_compr_audio *prtd;
3716 int ret = 0;
3717 struct msm_adsp_event_data *event_data = NULL;
3718
3719 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3720 pr_err("%s Received invalid fe_id %lu\n",
3721 __func__, fe_id);
3722 ret = -EINVAL;
3723 goto done;
3724 }
3725
3726 cstream = pdata->cstream[fe_id];
3727 if (cstream == NULL) {
3728 pr_err("%s cstream is null\n", __func__);
3729 ret = -EINVAL;
3730 goto done;
3731 }
3732
3733 prtd = cstream->runtime->private_data;
3734 if (!prtd) {
3735 pr_err("%s: prtd is null\n", __func__);
3736 ret = -EINVAL;
3737 goto done;
3738 }
3739
3740 if (prtd->audio_client == NULL) {
3741 pr_err("%s: audio_client is null\n", __func__);
3742 ret = -EINVAL;
3743 goto done;
3744 }
3745
3746 event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
3747 if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
3748 (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
3749 pr_err("%s: invalid event_type=%d",
3750 __func__, event_data->event_type);
3751 ret = -EINVAL;
3752 goto done;
3753 }
3754
Xiaojun Sang75642c32018-03-23 08:57:33 +08003755 if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
3756 - sizeof(struct msm_adsp_event_data)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303757 pr_err("%s param length=%d exceeds limit",
3758 __func__, event_data->payload_len);
3759 ret = -EINVAL;
3760 goto done;
3761 }
3762
3763 ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
3764 if (ret < 0)
3765 pr_err("%s: failed to send stream event cmd, err = %d\n",
3766 __func__, ret);
3767done:
3768 return ret;
3769}
3770
3771static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol,
3772 struct snd_ctl_elem_value *ucontrol)
3773{
3774 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3775 unsigned long fe_id = kcontrol->private_value;
3776 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3777 snd_soc_component_get_drvdata(comp);
3778 struct snd_compr_stream *cstream = NULL;
3779 struct msm_compr_audio *prtd;
3780 int fd;
3781 int ret = 0;
3782
3783 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3784 pr_err("%s Received out of bounds invalid fe_id %lu\n",
3785 __func__, fe_id);
3786 ret = -EINVAL;
3787 goto done;
3788 }
3789
3790 cstream = pdata->cstream[fe_id];
3791 if (cstream == NULL) {
3792 pr_err("%s cstream is null\n", __func__);
3793 ret = -EINVAL;
3794 goto done;
3795 }
3796
3797 prtd = cstream->runtime->private_data;
3798 if (!prtd) {
3799 pr_err("%s: prtd is null\n", __func__);
3800 ret = -EINVAL;
3801 goto done;
3802 }
3803
3804 if (prtd->audio_client == NULL) {
3805 pr_err("%s: audio_client is null\n", __func__);
3806 ret = -EINVAL;
3807 goto done;
3808 }
3809
3810 memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd));
3811 ret = q6asm_send_ion_fd(prtd->audio_client, fd);
3812 if (ret < 0)
3813 pr_err("%s: failed to register ion fd\n", __func__);
3814done:
3815 return ret;
3816}
3817
3818static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
3819 struct snd_ctl_elem_value *ucontrol)
3820{
3821 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3822 unsigned long fe_id = kcontrol->private_value;
3823 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3824 snd_soc_component_get_drvdata(comp);
3825 struct snd_compr_stream *cstream = NULL;
3826 struct msm_compr_audio *prtd;
3827 int ret = 0;
3828 int param_length = 0;
3829
3830 if (fe_id >= MSM_FRONTEND_DAI_MAX) {
3831 pr_err("%s Received invalid fe_id %lu\n",
3832 __func__, fe_id);
3833 ret = -EINVAL;
3834 goto done;
3835 }
3836
3837 cstream = pdata->cstream[fe_id];
3838 if (cstream == NULL) {
3839 pr_err("%s cstream is null\n", __func__);
3840 ret = -EINVAL;
3841 goto done;
3842 }
3843
3844 prtd = cstream->runtime->private_data;
3845 if (!prtd) {
3846 pr_err("%s: prtd is null\n", __func__);
3847 ret = -EINVAL;
3848 goto done;
3849 }
3850
3851 if (prtd->audio_client == NULL) {
3852 pr_err("%s: audio_client is null\n", __func__);
3853 ret = -EINVAL;
3854 goto done;
3855 }
3856
3857 memcpy(&param_length, ucontrol->value.bytes.data,
3858 sizeof(param_length));
3859 if ((param_length + sizeof(param_length))
3860 >= sizeof(ucontrol->value.bytes.data)) {
3861 pr_err("%s param length=%d exceeds limit",
3862 __func__, param_length);
3863 ret = -EINVAL;
3864 goto done;
3865 }
3866
3867 ret = q6asm_send_rtic_event_ack(prtd->audio_client,
3868 ucontrol->value.bytes.data + sizeof(param_length),
3869 param_length);
3870 if (ret < 0)
3871 pr_err("%s: failed to send rtic event ack, err = %d\n",
3872 __func__, ret);
3873done:
3874 return ret;
3875}
3876
3877static int msm_compr_gapless_put(struct snd_kcontrol *kcontrol,
3878 struct snd_ctl_elem_value *ucontrol)
3879{
3880 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3881 struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
3882 snd_soc_component_get_drvdata(comp);
3883 pdata->use_dsp_gapless_mode = ucontrol->value.integer.value[0];
3884 pr_debug("%s: value: %ld\n", __func__,
3885 ucontrol->value.integer.value[0]);
3886
3887 return 0;
3888}
3889
3890static int msm_compr_gapless_get(struct snd_kcontrol *kcontrol,
3891 struct snd_ctl_elem_value *ucontrol)
3892{
3893 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
3894 struct msm_compr_pdata *pdata =
3895 snd_soc_component_get_drvdata(comp);
3896 pr_debug("%s:gapless mode %d\n", __func__, pdata->use_dsp_gapless_mode);
3897 ucontrol->value.integer.value[0] = pdata->use_dsp_gapless_mode;
3898
3899 return 0;
3900}
3901
3902static const struct snd_kcontrol_new msm_compr_gapless_controls[] = {
3903 SOC_SINGLE_EXT("Compress Gapless Playback",
3904 0, 0, 1, 0,
3905 msm_compr_gapless_get,
3906 msm_compr_gapless_put),
3907};
3908
3909static int msm_compr_probe(struct snd_soc_platform *platform)
3910{
3911 struct msm_compr_pdata *pdata;
3912 int i;
3913 int rc;
3914 const char *qdsp_version;
3915
3916 pr_debug("%s\n", __func__);
3917 pdata = (struct msm_compr_pdata *)
3918 kzalloc(sizeof(*pdata), GFP_KERNEL);
3919 if (!pdata)
3920 return -ENOMEM;
3921
3922 snd_soc_platform_set_drvdata(platform, pdata);
3923
3924 for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) {
3925 pdata->volume[i][0] = COMPRESSED_LR_VOL_MAX_STEPS;
3926 pdata->volume[i][1] = COMPRESSED_LR_VOL_MAX_STEPS;
3927 pdata->audio_effects[i] = NULL;
3928 pdata->dec_params[i] = NULL;
3929 pdata->cstream[i] = NULL;
3930 pdata->ch_map[i] = NULL;
Aditya Bavanari9deef912017-11-20 13:31:31 +05303931 pdata->is_in_use[i] = false;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303932 }
3933
3934 snd_soc_add_platform_controls(platform, msm_compr_gapless_controls,
3935 ARRAY_SIZE(msm_compr_gapless_controls));
3936
3937 rc = of_property_read_string(platform->dev->of_node,
3938 "qcom,adsp-version", &qdsp_version);
3939 if (!rc) {
3940 if (!strcmp(qdsp_version, "MDSP 1.2"))
3941 pdata->use_legacy_api = true;
3942 else
3943 pdata->use_legacy_api = false;
3944 } else
3945 pdata->use_legacy_api = false;
3946
3947 pr_debug("%s: use legacy api %d\n", __func__, pdata->use_legacy_api);
3948 /*
3949 * use_dsp_gapless_mode part of platform data(pdata) is updated from HAL
3950 * through a mixer control before compress driver is opened. The mixer
3951 * control is used to decide if dsp gapless mode needs to be enabled.
3952 * Gapless is disabled by default.
3953 */
3954 pdata->use_dsp_gapless_mode = false;
3955 return 0;
3956}
3957
3958static int msm_compr_volume_info(struct snd_kcontrol *kcontrol,
3959 struct snd_ctl_elem_info *uinfo)
3960{
3961 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3962 uinfo->count = 2;
3963 uinfo->value.integer.min = 0;
3964 uinfo->value.integer.max = COMPRESSED_LR_VOL_MAX_STEPS;
3965 return 0;
3966}
3967
3968static int msm_compr_audio_effects_config_info(struct snd_kcontrol *kcontrol,
3969 struct snd_ctl_elem_info *uinfo)
3970{
3971 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3972 uinfo->count = MAX_PP_PARAMS_SZ;
3973 uinfo->value.integer.min = 0;
3974 uinfo->value.integer.max = 0xFFFFFFFF;
3975 return 0;
3976}
3977
3978static int msm_compr_query_audio_effect_info(struct snd_kcontrol *kcontrol,
3979 struct snd_ctl_elem_info *uinfo)
3980{
3981 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3982 uinfo->count = 128;
3983 uinfo->value.integer.min = 0;
3984 uinfo->value.integer.max = 0xFFFFFFFF;
3985 return 0;
3986}
3987
3988static int msm_compr_dec_params_info(struct snd_kcontrol *kcontrol,
3989 struct snd_ctl_elem_info *uinfo)
3990{
3991 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
3992 uinfo->count = 128;
3993 uinfo->value.integer.min = 0;
3994 uinfo->value.integer.max = 0xFFFFFFFF;
3995 return 0;
3996}
3997
3998static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol,
3999 struct snd_ctl_elem_info *uinfo)
4000{
4001 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
4002 uinfo->count = 5;
4003 uinfo->value.integer.min = 0;
4004 uinfo->value.integer.max = 0xFFFFFFFF;
4005 return 0;
4006}
4007
4008static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol,
4009 struct snd_ctl_elem_info *uinfo)
4010{
4011 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
Dieter Lueckingceef9af2018-09-28 15:09:32 +02004012 uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304013 uinfo->value.integer.min = 0;
Dieter Lueckingceef9af2018-09-28 15:09:32 +02004014 /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */
4015 uinfo->value.integer.max = 34;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304016 return 0;
4017}
4018
4019static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd)
4020{
4021 const char *mixer_ctl_name = "Compress Playback";
4022 const char *deviceNo = "NN";
4023 const char *suffix = "Volume";
4024 char *mixer_str = NULL;
4025 int ctl_len;
4026 struct snd_kcontrol_new fe_volume_control[1] = {
4027 {
4028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4029 .name = "?",
4030 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
4031 SNDRV_CTL_ELEM_ACCESS_READWRITE,
4032 .info = msm_compr_volume_info,
4033 .tlv.p = msm_compr_vol_gain,
4034 .get = msm_compr_volume_get,
4035 .put = msm_compr_volume_put,
4036 .private_value = 0,
4037 }
4038 };
4039
4040 if (!rtd) {
4041 pr_err("%s NULL rtd\n", __func__);
4042 return 0;
4043 }
4044 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4045 __func__, rtd->dai_link->name, rtd->dai_link->id,
4046 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4047 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
4048 strlen(suffix) + 1;
4049 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4050 if (!mixer_str) {
4051 pr_err("failed to allocate mixer ctrl str of len %d", ctl_len);
4052 return 0;
4053 }
4054 snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
4055 rtd->pcm->device, suffix);
4056 fe_volume_control[0].name = mixer_str;
4057 fe_volume_control[0].private_value = rtd->dai_link->id;
4058 pr_debug("Registering new mixer ctl %s", mixer_str);
4059 snd_soc_add_platform_controls(rtd->platform, fe_volume_control,
4060 ARRAY_SIZE(fe_volume_control));
4061 kfree(mixer_str);
4062 return 0;
4063}
4064
4065static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd)
4066{
4067 const char *mixer_ctl_name = "Audio Effects Config";
4068 const char *deviceNo = "NN";
4069 char *mixer_str = NULL;
4070 int ctl_len;
4071 struct snd_kcontrol_new fe_audio_effects_config_control[1] = {
4072 {
4073 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4074 .name = "?",
4075 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4076 .info = msm_compr_audio_effects_config_info,
4077 .get = msm_compr_audio_effects_config_get,
4078 .put = msm_compr_audio_effects_config_put,
4079 .private_value = 0,
4080 }
4081 };
4082
4083
4084 if (!rtd) {
4085 pr_err("%s NULL rtd\n", __func__);
4086 return 0;
4087 }
4088
4089 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4090 __func__, rtd->dai_link->name, rtd->dai_link->id,
4091 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4092
4093 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4094 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4095
4096 if (!mixer_str)
4097 return 0;
4098
4099 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4100
4101 fe_audio_effects_config_control[0].name = mixer_str;
4102 fe_audio_effects_config_control[0].private_value = rtd->dai_link->id;
4103 pr_debug("Registering new mixer ctl %s\n", mixer_str);
4104 snd_soc_add_platform_controls(rtd->platform,
4105 fe_audio_effects_config_control,
4106 ARRAY_SIZE(fe_audio_effects_config_control));
4107 kfree(mixer_str);
4108 return 0;
4109}
4110
4111static int msm_compr_add_query_audio_effect_control(
4112 struct snd_soc_pcm_runtime *rtd)
4113{
4114 const char *mixer_ctl_name = "Query Audio Effect Param";
4115 const char *deviceNo = "NN";
4116 char *mixer_str = NULL;
4117 int ctl_len;
4118 struct snd_kcontrol_new fe_query_audio_effect_control[1] = {
4119 {
4120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4121 .name = "?",
4122 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4123 .info = msm_compr_query_audio_effect_info,
4124 .get = msm_compr_query_audio_effect_get,
4125 .put = msm_compr_query_audio_effect_put,
4126 .private_value = 0,
4127 }
4128 };
4129 if (!rtd) {
4130 pr_err("%s NULL rtd\n", __func__);
4131 return 0;
4132 }
4133 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4134 __func__, rtd->dai_link->name, rtd->dai_link->id,
4135 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4136 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4137 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4138 if (!mixer_str) {
4139 pr_err("failed to allocate mixer ctrl str of len %d", ctl_len);
4140 return 0;
4141 }
4142 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4143 fe_query_audio_effect_control[0].name = mixer_str;
4144 fe_query_audio_effect_control[0].private_value = rtd->dai_link->id;
4145 pr_debug("%s: registering new mixer ctl %s\n", __func__, mixer_str);
4146 snd_soc_add_platform_controls(rtd->platform,
4147 fe_query_audio_effect_control,
4148 ARRAY_SIZE(fe_query_audio_effect_control));
4149 kfree(mixer_str);
4150 return 0;
4151}
4152
4153static int msm_compr_add_audio_adsp_stream_cmd_control(
4154 struct snd_soc_pcm_runtime *rtd)
4155{
4156 const char *mixer_ctl_name = DSP_STREAM_CMD;
4157 const char *deviceNo = "NN";
4158 char *mixer_str = NULL;
4159 int ctl_len = 0, ret = 0;
4160 struct snd_kcontrol_new fe_audio_adsp_stream_cmd_config_control[1] = {
4161 {
4162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4163 .name = "?",
4164 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4165 .info = msm_adsp_stream_cmd_info,
4166 .put = msm_compr_adsp_stream_cmd_put,
4167 .private_value = 0,
4168 }
4169 };
4170
4171 if (!rtd) {
4172 pr_err("%s NULL rtd\n", __func__);
4173 ret = -EINVAL;
4174 goto done;
4175 }
4176
4177 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4178 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4179 if (!mixer_str) {
4180 ret = -ENOMEM;
4181 goto done;
4182 }
4183
4184 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4185 fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str;
4186 fe_audio_adsp_stream_cmd_config_control[0].private_value =
4187 rtd->dai_link->id;
4188 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4189 ret = snd_soc_add_platform_controls(rtd->platform,
4190 fe_audio_adsp_stream_cmd_config_control,
4191 ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control));
4192 if (ret < 0)
4193 pr_err("%s: failed to add ctl %s. err = %d\n",
4194 __func__, mixer_str, ret);
4195
4196 kfree(mixer_str);
4197done:
4198 return ret;
4199}
4200
4201static int msm_compr_add_audio_adsp_stream_callback_control(
4202 struct snd_soc_pcm_runtime *rtd)
4203{
4204 const char *mixer_ctl_name = DSP_STREAM_CALLBACK;
4205 const char *deviceNo = "NN";
4206 char *mixer_str = NULL;
4207 int ctl_len = 0, ret = 0;
4208 struct snd_kcontrol *kctl;
4209
4210 struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = {
4211 {
4212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4213 .name = "?",
4214 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4215 .info = msm_adsp_stream_callback_info,
4216 .get = msm_adsp_stream_callback_get,
4217 .private_value = 0,
4218 }
4219 };
4220
4221 if (!rtd) {
4222 pr_err("%s: rtd is NULL\n", __func__);
4223 ret = -EINVAL;
4224 goto done;
4225 }
4226
4227 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4228 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4229 if (!mixer_str) {
4230 ret = -ENOMEM;
4231 goto done;
4232 }
4233
4234 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4235 fe_audio_adsp_callback_config_control[0].name = mixer_str;
4236 fe_audio_adsp_callback_config_control[0].private_value =
4237 rtd->dai_link->id;
4238 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4239 ret = snd_soc_add_platform_controls(rtd->platform,
4240 fe_audio_adsp_callback_config_control,
4241 ARRAY_SIZE(fe_audio_adsp_callback_config_control));
4242 if (ret < 0) {
4243 pr_err("%s: failed to add ctl %s. err = %d\n",
4244 __func__, mixer_str, ret);
4245 ret = -EINVAL;
4246 goto free_mixer_str;
4247 }
4248
4249 kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
4250 if (!kctl) {
4251 pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
4252 ret = -EINVAL;
4253 goto free_mixer_str;
4254 }
4255
4256 kctl->private_data = NULL;
4257
4258free_mixer_str:
4259 kfree(mixer_str);
4260done:
4261 return ret;
4262}
4263
4264static int msm_compr_add_dec_runtime_params_control(
4265 struct snd_soc_pcm_runtime *rtd)
4266{
4267 const char *mixer_ctl_name = "Audio Stream";
4268 const char *deviceNo = "NN";
4269 const char *suffix = "Dec Params";
4270 char *mixer_str = NULL;
4271 int ctl_len;
4272 struct snd_kcontrol_new fe_dec_params_control[1] = {
4273 {
4274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4275 .name = "?",
4276 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4277 .info = msm_compr_dec_params_info,
4278 .get = msm_compr_dec_params_get,
4279 .put = msm_compr_dec_params_put,
4280 .private_value = 0,
4281 }
4282 };
4283
4284 if (!rtd) {
4285 pr_err("%s NULL rtd\n", __func__);
4286 return 0;
4287 }
4288
4289 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4290 __func__, rtd->dai_link->name, rtd->dai_link->id,
4291 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4292
4293 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
4294 strlen(suffix) + 1;
4295 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4296
4297 if (!mixer_str)
4298 return 0;
4299
4300 snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
4301 rtd->pcm->device, suffix);
4302
4303 fe_dec_params_control[0].name = mixer_str;
4304 fe_dec_params_control[0].private_value = rtd->dai_link->id;
4305 pr_debug("Registering new mixer ctl %s", mixer_str);
4306 snd_soc_add_platform_controls(rtd->platform,
4307 fe_dec_params_control,
4308 ARRAY_SIZE(fe_dec_params_control));
4309 kfree(mixer_str);
4310 return 0;
4311}
4312
4313static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd)
4314{
4315 const char *playback_mixer_ctl_name = "Audio Stream";
4316 const char *capture_mixer_ctl_name = "Audio Stream Capture";
4317 const char *deviceNo = "NN";
4318 const char *suffix = "App Type Cfg";
4319 char *mixer_str = NULL;
4320 int ctl_len;
4321 struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
4322 {
4323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4324 .name = "?",
4325 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4326 .info = msm_compr_app_type_cfg_info,
4327 .put = msm_compr_playback_app_type_cfg_put,
4328 .get = msm_compr_playback_app_type_cfg_get,
4329 .private_value = 0,
4330 }
4331 };
4332
4333 if (!rtd) {
4334 pr_err("%s NULL rtd\n", __func__);
4335 return 0;
4336 }
4337
4338 pr_debug("%s: added new compr FE ctl with name %s, id %d, cpu dai %s, device no %d\n",
4339 __func__, rtd->dai_link->name, rtd->dai_link->id,
4340 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4341 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK)
4342 ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo)
4343 + 1 + strlen(suffix) + 1;
4344 else
4345 ctl_len = strlen(capture_mixer_ctl_name) + 1 + strlen(deviceNo)
4346 + 1 + strlen(suffix) + 1;
4347
4348 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4349
4350 if (!mixer_str)
4351 return 0;
4352
4353 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK)
4354 snprintf(mixer_str, ctl_len, "%s %d %s",
4355 playback_mixer_ctl_name, rtd->pcm->device, suffix);
4356 else
4357 snprintf(mixer_str, ctl_len, "%s %d %s",
4358 capture_mixer_ctl_name, rtd->pcm->device, suffix);
4359
4360 fe_app_type_cfg_control[0].name = mixer_str;
4361 fe_app_type_cfg_control[0].private_value = rtd->dai_link->id;
4362
4363 if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) {
4364 fe_app_type_cfg_control[0].put =
4365 msm_compr_playback_app_type_cfg_put;
4366 fe_app_type_cfg_control[0].get =
4367 msm_compr_playback_app_type_cfg_get;
4368 } else {
4369 fe_app_type_cfg_control[0].put =
4370 msm_compr_capture_app_type_cfg_put;
4371 fe_app_type_cfg_control[0].get =
4372 msm_compr_capture_app_type_cfg_get;
4373 }
4374 pr_debug("Registering new mixer ctl %s", mixer_str);
4375 snd_soc_add_platform_controls(rtd->platform,
4376 fe_app_type_cfg_control,
4377 ARRAY_SIZE(fe_app_type_cfg_control));
4378 kfree(mixer_str);
4379 return 0;
4380}
4381
4382static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd)
4383{
4384 const char *mixer_ctl_name = "Playback Channel Map";
4385 const char *deviceNo = "NN";
4386 char *mixer_str = NULL;
4387 struct msm_compr_pdata *pdata = NULL;
4388 int ctl_len;
4389 struct snd_kcontrol_new fe_channel_map_control[1] = {
4390 {
4391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4392 .name = "?",
4393 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4394 .info = msm_compr_channel_map_info,
4395 .get = msm_compr_channel_map_get,
4396 .put = msm_compr_channel_map_put,
4397 .private_value = 0,
4398 }
4399 };
4400
4401 if (!rtd) {
4402 pr_err("%s: NULL rtd\n", __func__);
4403 return -EINVAL;
4404 }
4405
4406 pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
4407 __func__, rtd->dai_link->name, rtd->dai_link->id,
4408 rtd->dai_link->cpu_dai_name, rtd->pcm->device);
4409
4410 ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1;
4411 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4412
4413 if (!mixer_str)
4414 return -ENOMEM;
4415
4416 snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device);
4417
4418 fe_channel_map_control[0].name = mixer_str;
4419 fe_channel_map_control[0].private_value = rtd->dai_link->id;
4420 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4421 snd_soc_add_platform_controls(rtd->platform,
4422 fe_channel_map_control,
4423 ARRAY_SIZE(fe_channel_map_control));
4424
4425 pdata = snd_soc_platform_get_drvdata(rtd->platform);
4426 pdata->ch_map[rtd->dai_link->id] =
4427 kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL);
4428 if (!pdata->ch_map[rtd->dai_link->id]) {
4429 pr_err("%s: Could not allocate memory for channel map\n",
4430 __func__);
4431 kfree(mixer_str);
4432 return -ENOMEM;
4433 }
4434 kfree(mixer_str);
4435 return 0;
4436}
4437
4438static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd)
4439{
4440 const char *mixer_ctl_name = "Playback ION FD";
4441 const char *deviceNo = "NN";
4442 char *mixer_str = NULL;
4443 int ctl_len = 0, ret = 0;
4444 struct snd_kcontrol_new fe_ion_fd_config_control[1] = {
4445 {
4446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4447 .name = "?",
4448 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4449 .info = msm_adsp_stream_cmd_info,
4450 .put = msm_compr_ion_fd_map_put,
4451 .private_value = 0,
4452 }
4453 };
4454
4455 if (!rtd) {
4456 pr_err("%s NULL rtd\n", __func__);
4457 ret = -EINVAL;
4458 goto done;
4459 }
4460
4461 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4462 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4463 if (!mixer_str) {
4464 ret = -ENOMEM;
4465 goto done;
4466 }
4467
4468 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4469 fe_ion_fd_config_control[0].name = mixer_str;
4470 fe_ion_fd_config_control[0].private_value = rtd->dai_link->id;
4471 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4472 ret = snd_soc_add_platform_controls(rtd->platform,
4473 fe_ion_fd_config_control,
4474 ARRAY_SIZE(fe_ion_fd_config_control));
4475 if (ret < 0)
4476 pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
4477
4478 kfree(mixer_str);
4479done:
4480 return ret;
4481}
4482
4483static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd)
4484{
4485 const char *mixer_ctl_name = "Playback Event Ack";
4486 const char *deviceNo = "NN";
4487 char *mixer_str = NULL;
4488 int ctl_len = 0, ret = 0;
4489 struct snd_kcontrol_new fe_event_ack_config_control[1] = {
4490 {
4491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4492 .name = "?",
4493 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
4494 .info = msm_adsp_stream_cmd_info,
4495 .put = msm_compr_rtic_event_ack_put,
4496 .private_value = 0,
4497 }
4498 };
4499
4500 if (!rtd) {
4501 pr_err("%s NULL rtd\n", __func__);
4502 ret = -EINVAL;
4503 goto done;
4504 }
4505
4506 ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
4507 mixer_str = kzalloc(ctl_len, GFP_KERNEL);
4508 if (!mixer_str) {
4509 ret = -ENOMEM;
4510 goto done;
4511 }
4512
4513 snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
4514 fe_event_ack_config_control[0].name = mixer_str;
4515 fe_event_ack_config_control[0].private_value = rtd->dai_link->id;
4516 pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
4517 ret = snd_soc_add_platform_controls(rtd->platform,
4518 fe_event_ack_config_control,
4519 ARRAY_SIZE(fe_event_ack_config_control));
4520 if (ret < 0)
4521 pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
4522
4523 kfree(mixer_str);
4524done:
4525 return ret;
4526}
4527
4528static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
4529{
4530 int rc;
4531
4532 rc = msm_compr_add_volume_control(rtd);
4533 if (rc)
4534 pr_err("%s: Could not add Compr Volume Control\n", __func__);
4535
4536 rc = msm_compr_add_audio_effects_control(rtd);
4537 if (rc)
4538 pr_err("%s: Could not add Compr Audio Effects Control\n",
4539 __func__);
4540
4541 rc = msm_compr_add_audio_adsp_stream_cmd_control(rtd);
4542 if (rc)
4543 pr_err("%s: Could not add Compr ADSP Stream Cmd Control\n",
4544 __func__);
4545
4546 rc = msm_compr_add_audio_adsp_stream_callback_control(rtd);
4547 if (rc)
4548 pr_err("%s: Could not add Compr ADSP Stream Callback Control\n",
4549 __func__);
4550
4551 rc = msm_compr_add_io_fd_cmd_control(rtd);
4552 if (rc)
4553 pr_err("%s: Could not add Compr ion fd Control\n",
4554 __func__);
4555
4556 rc = msm_compr_add_event_ack_cmd_control(rtd);
4557 if (rc)
4558 pr_err("%s: Could not add Compr event ack Control\n",
4559 __func__);
4560
4561 rc = msm_compr_add_query_audio_effect_control(rtd);
4562 if (rc)
4563 pr_err("%s: Could not add Compr Query Audio Effect Control\n",
4564 __func__);
4565
4566 rc = msm_compr_add_dec_runtime_params_control(rtd);
4567 if (rc)
4568 pr_err("%s: Could not add Compr Dec runtime params Control\n",
4569 __func__);
4570 rc = msm_compr_add_app_type_cfg_control(rtd);
4571 if (rc)
4572 pr_err("%s: Could not add Compr App Type Cfg Control\n",
4573 __func__);
4574 rc = msm_compr_add_channel_map_control(rtd);
4575 if (rc)
4576 pr_err("%s: Could not add Compr Channel Map Control\n",
4577 __func__);
4578 return 0;
4579}
4580
4581static struct snd_compr_ops msm_compr_ops = {
4582 .open = msm_compr_open,
4583 .free = msm_compr_free,
4584 .trigger = msm_compr_trigger,
4585 .pointer = msm_compr_pointer,
4586 .set_params = msm_compr_set_params,
4587 .set_metadata = msm_compr_set_metadata,
4588 .get_metadata = msm_compr_get_metadata,
4589 .set_next_track_param = msm_compr_set_next_track_param,
4590 .ack = msm_compr_ack,
4591 .copy = msm_compr_copy,
4592 .get_caps = msm_compr_get_caps,
4593 .get_codec_caps = msm_compr_get_codec_caps,
4594};
4595
4596static struct snd_soc_platform_driver msm_soc_platform = {
4597 .probe = msm_compr_probe,
4598 .compr_ops = &msm_compr_ops,
4599 .pcm_new = msm_compr_new,
4600};
4601
4602static int msm_compr_dev_probe(struct platform_device *pdev)
4603{
4604
4605 pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
4606 return snd_soc_register_platform(&pdev->dev,
4607 &msm_soc_platform);
4608}
4609
4610static int msm_compr_remove(struct platform_device *pdev)
4611{
4612 snd_soc_unregister_platform(&pdev->dev);
4613 return 0;
4614}
4615
4616static const struct of_device_id msm_compr_dt_match[] = {
4617 {.compatible = "qcom,msm-compress-dsp"},
4618 {}
4619};
4620MODULE_DEVICE_TABLE(of, msm_compr_dt_match);
4621
4622static struct platform_driver msm_compr_driver = {
4623 .driver = {
4624 .name = "msm-compress-dsp",
4625 .owner = THIS_MODULE,
4626 .of_match_table = msm_compr_dt_match,
4627 },
4628 .probe = msm_compr_dev_probe,
4629 .remove = msm_compr_remove,
4630};
4631
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05304632int __init msm_compress_dsp_init(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304633{
4634 return platform_driver_register(&msm_compr_driver);
4635}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304636
Asish Bhattacharya5faacb32017-12-04 17:23:15 +05304637void msm_compress_dsp_exit(void)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304638{
4639 platform_driver_unregister(&msm_compr_driver);
4640}
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05304641
4642MODULE_DESCRIPTION("Compress Offload platform driver");
4643MODULE_LICENSE("GPL v2");