2 * sst_stream.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-14 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@intel.com>
7 * Dharageswari R <dharageswari.r@intel.com>
8 * KP Jeeja <jeeja.kp@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 #include <linux/pci.h>
23 #include <linux/firmware.h>
24 #include <linux/sched.h>
25 #include <linux/delay.h>
26 #include <linux/pm_runtime.h>
27 #include <sound/core.h>
28 #include <sound/pcm.h>
29 #include <sound/soc.h>
30 #include <sound/compress_driver.h>
31 #include <asm/platform_sst_audio.h>
32 #include "../sst-mfld-platform.h"
34 #include "../sst-dsp.h"
36 int sst_alloc_stream_mrfld(struct intel_sst_drv
*sst_drv_ctx
, void *params
)
38 struct snd_sst_alloc_mrfld alloc_param
;
39 struct snd_sst_params
*str_params
;
40 struct snd_sst_tstamp fw_tstamp
;
41 struct stream_info
*str_info
;
42 struct snd_sst_alloc_response
*response
;
43 unsigned int str_id
, pipe_id
, task_id
;
44 int i
, num_ch
, ret
= 0;
47 dev_dbg(sst_drv_ctx
->dev
, "Enter\n");
50 str_params
= (struct snd_sst_params
*)params
;
51 memset(&alloc_param
, 0, sizeof(alloc_param
));
52 alloc_param
.operation
= str_params
->ops
;
53 alloc_param
.codec_type
= str_params
->codec
;
54 alloc_param
.sg_count
= str_params
->aparams
.sg_count
;
55 alloc_param
.ring_buf_info
[0].addr
=
56 str_params
->aparams
.ring_buf_info
[0].addr
;
57 alloc_param
.ring_buf_info
[0].size
=
58 str_params
->aparams
.ring_buf_info
[0].size
;
59 alloc_param
.frag_size
= str_params
->aparams
.frag_size
;
61 memcpy(&alloc_param
.codec_params
, &str_params
->sparams
,
62 sizeof(struct snd_sst_stream_params
));
65 * fill channel map params for multichannel support.
66 * Ideally channel map should be received from upper layers
67 * for multichannel support.
68 * Currently hardcoding as per FW reqm.
70 num_ch
= sst_get_num_channel(str_params
);
71 for (i
= 0; i
< 8; i
++) {
73 alloc_param
.codec_params
.uc
.pcm_params
.channel_map
[i
] = i
;
75 alloc_param
.codec_params
.uc
.pcm_params
.channel_map
[i
] = 0xFF;
78 str_id
= str_params
->stream_id
;
79 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
80 if (str_info
== NULL
) {
81 dev_err(sst_drv_ctx
->dev
, "get stream info returned null\n");
85 pipe_id
= str_params
->device_type
;
86 task_id
= str_params
->task
;
87 sst_drv_ctx
->streams
[str_id
].pipe_id
= pipe_id
;
88 sst_drv_ctx
->streams
[str_id
].task_id
= task_id
;
89 sst_drv_ctx
->streams
[str_id
].num_ch
= num_ch
;
91 if (sst_drv_ctx
->info
.lpe_viewpt_rqd
)
92 alloc_param
.ts
= sst_drv_ctx
->info
.mailbox_start
+
93 sst_drv_ctx
->tstamp
+ (str_id
* sizeof(fw_tstamp
));
95 alloc_param
.ts
= sst_drv_ctx
->mailbox_add
+
96 sst_drv_ctx
->tstamp
+ (str_id
* sizeof(fw_tstamp
));
98 dev_dbg(sst_drv_ctx
->dev
, "alloc tstamp location = 0x%x\n",
100 dev_dbg(sst_drv_ctx
->dev
, "assigned pipe id 0x%x to task %d\n",
103 /* allocate device type context */
104 sst_init_stream(&sst_drv_ctx
->streams
[str_id
], alloc_param
.codec_type
,
105 str_id
, alloc_param
.operation
, 0);
107 dev_info(sst_drv_ctx
->dev
, "Alloc for str %d pipe %#x\n",
109 ret
= sst_prepare_and_post_msg(sst_drv_ctx
, task_id
, IPC_CMD
,
110 IPC_IA_ALLOC_STREAM_MRFLD
, pipe_id
, sizeof(alloc_param
),
111 &alloc_param
, data
, true, true, false, true);
114 dev_err(sst_drv_ctx
->dev
, "FW alloc failed ret %d\n", ret
);
115 /* alloc failed, so reset the state to uninit */
116 str_info
->status
= STREAM_UN_INIT
;
119 response
= (struct snd_sst_alloc_response
*)data
;
120 ret
= response
->str_type
.result
;
123 dev_err(sst_drv_ctx
->dev
, "FW alloc failed ret %d\n", ret
);
124 if (ret
== SST_ERR_STREAM_IN_USE
) {
125 dev_err(sst_drv_ctx
->dev
,
126 "FW not in clean state, send free for:%d\n", str_id
);
127 sst_free_stream(sst_drv_ctx
, str_id
);
137 * sst_start_stream - Send msg for a starting stream
140 * This function is called by any function which wants to start
143 int sst_start_stream(struct intel_sst_drv
*sst_drv_ctx
, int str_id
)
146 struct stream_info
*str_info
;
149 dev_dbg(sst_drv_ctx
->dev
, "sst_start_stream for %d\n", str_id
);
150 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
153 if (str_info
->status
!= STREAM_RUNNING
)
156 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
,
157 IPC_CMD
, IPC_IA_START_STREAM_MRFLD
, str_info
->pipe_id
,
158 sizeof(u16
), &data
, NULL
, true, true, true, false);
163 int sst_send_byte_stream_mrfld(struct intel_sst_drv
*sst_drv_ctx
,
164 struct snd_sst_bytes_v2
*bytes
)
165 { struct ipc_post
*msg
= NULL
;
168 struct sst_block
*block
= NULL
;
170 dev_dbg(sst_drv_ctx
->dev
,
171 "type:%u ipc_msg:%u block:%u task_id:%u pipe: %#x length:%#x\n",
172 bytes
->type
, bytes
->ipc_msg
, bytes
->block
, bytes
->task_id
,
173 bytes
->pipe_id
, bytes
->len
);
175 if (sst_create_ipc_msg(&msg
, true))
178 pvt_id
= sst_assign_pvt_id(sst_drv_ctx
);
179 sst_fill_header_mrfld(&msg
->mrfld_header
, bytes
->ipc_msg
,
180 bytes
->task_id
, 1, pvt_id
);
181 msg
->mrfld_header
.p
.header_high
.part
.res_rqd
= bytes
->block
;
183 msg
->mrfld_header
.p
.header_low_payload
= length
;
184 dev_dbg(sst_drv_ctx
->dev
, "length is %d\n", length
);
185 memcpy(msg
->mailbox_data
, &bytes
->bytes
, bytes
->len
);
187 block
= sst_create_block(sst_drv_ctx
, bytes
->ipc_msg
, pvt_id
);
195 sst_add_to_dispatch_list_and_post(sst_drv_ctx
, msg
);
196 dev_dbg(sst_drv_ctx
->dev
, "msg->mrfld_header.p.header_low_payload:%d",
197 msg
->mrfld_header
.p
.header_low_payload
);
200 ret
= sst_wait_timeout(sst_drv_ctx
, block
);
202 dev_err(sst_drv_ctx
->dev
, "fw returned err %d\n", ret
);
203 sst_free_block(sst_drv_ctx
, block
);
207 if (bytes
->type
== SND_SST_BYTES_GET
) {
209 * copy the reply and send back
210 * we need to update only sz and payload
213 unsigned char *r
= block
->data
;
215 dev_dbg(sst_drv_ctx
->dev
, "read back %d bytes",
217 memcpy(bytes
->bytes
, r
, bytes
->len
);
221 sst_free_block(sst_drv_ctx
, block
);
223 test_and_clear_bit(pvt_id
, &sst_drv_ctx
->pvt_id
);
228 * sst_pause_stream - Send msg for a pausing stream
231 * This function is called by any function which wants to pause
232 * an already running stream.
234 int sst_pause_stream(struct intel_sst_drv
*sst_drv_ctx
, int str_id
)
237 struct stream_info
*str_info
;
239 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:sst_pause_stream for %d\n", str_id
);
240 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
243 if (str_info
->status
== STREAM_PAUSED
)
245 if (str_info
->status
== STREAM_RUNNING
||
246 str_info
->status
== STREAM_INIT
) {
247 if (str_info
->prev
== STREAM_UN_INIT
)
250 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
, IPC_CMD
,
251 IPC_IA_PAUSE_STREAM_MRFLD
, str_info
->pipe_id
,
252 0, NULL
, NULL
, true, true, false, true);
255 str_info
->prev
= str_info
->status
;
256 str_info
->status
= STREAM_PAUSED
;
257 } else if (retval
== SST_ERR_INVALID_STREAM_ID
) {
259 mutex_lock(&sst_drv_ctx
->sst_lock
);
260 sst_clean_stream(str_info
);
261 mutex_unlock(&sst_drv_ctx
->sst_lock
);
265 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:BADRQC for stream\n ");
272 * sst_resume_stream - Send msg for resuming stream
275 * This function is called by any function which wants to resume
276 * an already paused stream.
278 int sst_resume_stream(struct intel_sst_drv
*sst_drv_ctx
, int str_id
)
281 struct stream_info
*str_info
;
283 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:sst_resume_stream for %d\n", str_id
);
284 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
287 if (str_info
->status
== STREAM_RUNNING
)
289 if (str_info
->status
== STREAM_PAUSED
) {
290 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
,
291 IPC_CMD
, IPC_IA_RESUME_STREAM_MRFLD
,
292 str_info
->pipe_id
, 0, NULL
, NULL
,
293 true, true, false, true);
296 if (str_info
->prev
== STREAM_RUNNING
)
297 str_info
->status
= STREAM_RUNNING
;
299 str_info
->status
= STREAM_INIT
;
300 str_info
->prev
= STREAM_PAUSED
;
301 } else if (retval
== -SST_ERR_INVALID_STREAM_ID
) {
303 mutex_lock(&sst_drv_ctx
->sst_lock
);
304 sst_clean_stream(str_info
);
305 mutex_unlock(&sst_drv_ctx
->sst_lock
);
309 dev_err(sst_drv_ctx
->dev
, "SST ERR: BADQRC for stream\n");
317 * sst_drop_stream - Send msg for stopping stream
320 * This function is called by any function which wants to stop
323 int sst_drop_stream(struct intel_sst_drv
*sst_drv_ctx
, int str_id
)
326 struct stream_info
*str_info
;
328 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:sst_drop_stream for %d\n", str_id
);
329 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
333 if (str_info
->status
!= STREAM_UN_INIT
) {
334 str_info
->prev
= STREAM_UN_INIT
;
335 str_info
->status
= STREAM_INIT
;
336 str_info
->cumm_bytes
= 0;
337 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
,
338 IPC_CMD
, IPC_IA_DROP_STREAM_MRFLD
,
339 str_info
->pipe_id
, 0, NULL
, NULL
,
340 true, true, true, false);
343 dev_dbg(sst_drv_ctx
->dev
, "BADQRC for stream, state %x\n",
350 * sst_drain_stream - Send msg for draining stream
353 * This function is called by any function which wants to drain
356 int sst_drain_stream(struct intel_sst_drv
*sst_drv_ctx
,
357 int str_id
, bool partial_drain
)
360 struct stream_info
*str_info
;
362 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:sst_drain_stream for %d\n", str_id
);
363 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
366 if (str_info
->status
!= STREAM_RUNNING
&&
367 str_info
->status
!= STREAM_INIT
&&
368 str_info
->status
!= STREAM_PAUSED
) {
369 dev_err(sst_drv_ctx
->dev
, "SST ERR: BADQRC for stream = %d\n",
374 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
, IPC_CMD
,
375 IPC_IA_DRAIN_STREAM_MRFLD
, str_info
->pipe_id
,
376 sizeof(u8
), &partial_drain
, NULL
, true, true, false, false);
378 * with new non blocked drain implementation in core we dont need to
379 * wait for respsonse, and need to only invoke callback for drain
387 * sst_free_stream - Frees a stream
390 * This function is called by any function which wants to free
393 int sst_free_stream(struct intel_sst_drv
*sst_drv_ctx
, int str_id
)
396 struct stream_info
*str_info
;
397 struct intel_sst_ops
*ops
;
399 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:sst_free_stream for %d\n", str_id
);
401 mutex_lock(&sst_drv_ctx
->sst_lock
);
402 if (sst_drv_ctx
->sst_state
== SST_RESET
) {
403 mutex_unlock(&sst_drv_ctx
->sst_lock
);
406 mutex_unlock(&sst_drv_ctx
->sst_lock
);
407 str_info
= get_stream_info(sst_drv_ctx
, str_id
);
410 ops
= sst_drv_ctx
->ops
;
412 mutex_lock(&str_info
->lock
);
413 if (str_info
->status
!= STREAM_UN_INIT
) {
414 str_info
->prev
= str_info
->status
;
415 str_info
->status
= STREAM_UN_INIT
;
416 mutex_unlock(&str_info
->lock
);
418 dev_info(sst_drv_ctx
->dev
, "Free for str %d pipe %#x\n",
419 str_id
, str_info
->pipe_id
);
420 retval
= sst_prepare_and_post_msg(sst_drv_ctx
, str_info
->task_id
, IPC_CMD
,
421 IPC_IA_FREE_STREAM_MRFLD
, str_info
->pipe_id
, 0,
422 NULL
, NULL
, true, true, false, true);
424 dev_dbg(sst_drv_ctx
->dev
, "sst: wait for free returned %d\n",
426 mutex_lock(&sst_drv_ctx
->sst_lock
);
427 sst_clean_stream(str_info
);
428 mutex_unlock(&sst_drv_ctx
->sst_lock
);
429 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:Stream freed\n");
431 mutex_unlock(&str_info
->lock
);
433 dev_dbg(sst_drv_ctx
->dev
, "SST DBG:BADQRC for stream\n");