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