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