2 * intel_sst_pvt.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-10 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 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * This driver exposes the audio engine functionalities to the ALSA
29 * This file contains all private functions
32 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
34 #include <linux/pci.h>
36 #include <linux/firmware.h>
37 #include <linux/sched.h>
38 #include "intel_sst.h"
39 #include "intel_sst_ioctl.h"
40 #include "intel_sst_fw_ipc.h"
41 #include "intel_sst_common.h"
44 * sst_get_block_stream - get a new block stream
46 * @sst_drv_ctx: Driver context structure
48 * This function assigns a block for the calls that dont have stream context yet
49 * the blocks are used for waiting on Firmware's response for any operation
50 * Should be called with stream lock held
52 int sst_get_block_stream(struct intel_sst_drv
*sst_drv_ctx
)
56 for (i
= 0; i
< MAX_ACTIVE_STREAM
; i
++) {
57 if (sst_drv_ctx
->alloc_block
[i
].sst_id
== BLOCK_UNINIT
) {
58 sst_drv_ctx
->alloc_block
[i
].ops_block
.condition
= false;
59 sst_drv_ctx
->alloc_block
[i
].ops_block
.ret_code
= 0;
60 sst_drv_ctx
->alloc_block
[i
].sst_id
= 0;
64 if (i
== MAX_ACTIVE_STREAM
) {
65 pr_err("max alloc_stream reached\n");
66 i
= -EBUSY
; /* active stream limit reached */
72 * sst_wait_interruptible - wait on event
74 * @sst_drv_ctx: Driver context
75 * @block: Driver block to wait on
77 * This function waits without a timeout (and is interruptable) for a
80 int sst_wait_interruptible(struct intel_sst_drv
*sst_drv_ctx
,
81 struct sst_block
*block
)
85 if (!wait_event_interruptible(sst_drv_ctx
->wait_queue
,
88 if (block
->ret_code
< 0) {
89 pr_err("stream failed %d\n", block
->ret_code
);
92 pr_debug("event up\n");
96 pr_err("signal interrupted\n");
105 * sst_wait_interruptible_timeout - wait on event interruptable
107 * @sst_drv_ctx: Driver context
108 * @block: Driver block to wait on
109 * @timeout: time for wait on
111 * This function waits with a timeout value (and is interruptible) on a
114 int sst_wait_interruptible_timeout(
115 struct intel_sst_drv
*sst_drv_ctx
,
116 struct sst_block
*block
, int timeout
)
120 pr_debug("sst_wait_interruptible_timeout - waiting....\n");
121 if (wait_event_interruptible_timeout(sst_drv_ctx
->wait_queue
,
123 msecs_to_jiffies(timeout
))) {
124 if (block
->ret_code
< 0)
125 pr_err("stream failed %d\n", block
->ret_code
);
127 pr_debug("event up\n");
128 retval
= block
->ret_code
;
131 pr_err("timeout occurred...\n");
132 /*setting firmware state as uninit so that the
133 firmware will get re-downloaded on next request
134 this is because firmare not responding for 5 sec
135 is equalant to some unrecoverable error of FW
136 sst_drv_ctx->sst_state = SST_UN_INIT;*/
145 * sst_wait_timeout - wait on event for timeout
147 * @sst_drv_ctx: Driver context
148 * @block: Driver block to wait on
150 * This function waits with a timeout value (and is not interruptible) on a
153 int sst_wait_timeout(struct intel_sst_drv
*sst_drv_ctx
,
154 struct stream_alloc_block
*block
)
159 Observed that FW processes the alloc msg and replies even
160 before the alloc thread has finished execution */
161 pr_debug("waiting for %x, condition %x\n",
162 block
->sst_id
, block
->ops_block
.condition
);
163 if (wait_event_interruptible_timeout(sst_drv_ctx
->wait_queue
,
164 block
->ops_block
.condition
,
165 msecs_to_jiffies(SST_BLOCK_TIMEOUT
))) {
167 pr_debug("Event wake %x\n", block
->ops_block
.condition
);
168 pr_debug("message ret: %d\n", block
->ops_block
.ret_code
);
169 retval
= block
->ops_block
.ret_code
;
171 block
->ops_block
.on
= false;
172 pr_err("Wait timed-out %x\n", block
->ops_block
.condition
);
173 /* settign firmware state as uninit so that the
174 firmware will get redownloaded on next request
175 this is because firmare not responding for 5 sec
176 is equalant to some unrecoverable error of FW
177 sst_drv_ctx->sst_state = SST_UN_INIT;*/
185 * sst_create_large_msg - create a large IPC message
189 * this function allocates structures to send a large message to the firmware
191 int sst_create_large_msg(struct ipc_post
**arg
)
193 struct ipc_post
*msg
;
195 msg
= kzalloc(sizeof(struct ipc_post
), GFP_ATOMIC
);
197 pr_err("kzalloc msg failed\n");
201 msg
->mailbox_data
= kzalloc(SST_MAILBOX_SIZE
, GFP_ATOMIC
);
202 if (!msg
->mailbox_data
) {
204 pr_err("kzalloc mailbox_data failed");
212 * sst_create_short_msg - create a short IPC message
216 * this function allocates structures to send a short message to the firmware
218 int sst_create_short_msg(struct ipc_post
**arg
)
220 struct ipc_post
*msg
;
222 msg
= kzalloc(sizeof(*msg
), GFP_ATOMIC
);
224 pr_err("kzalloc msg failed\n");
227 msg
->mailbox_data
= NULL
;
233 * sst_clean_stream - clean the stream context
235 * @stream: stream structure
237 * this function resets the stream contexts
238 * should be called in free
240 void sst_clean_stream(struct stream_info
*stream
)
242 struct sst_stream_bufs
*bufs
= NULL
, *_bufs
;
243 stream
->status
= STREAM_UN_INIT
;
244 stream
->prev
= STREAM_UN_INIT
;
245 mutex_lock(&stream
->lock
);
246 list_for_each_entry_safe(bufs
, _bufs
, &stream
->bufs
, node
) {
247 list_del(&bufs
->node
);
250 mutex_unlock(&stream
->lock
);
252 if (stream
->ops
!= STREAM_OPS_PLAYBACK_DRM
)
253 kfree(stream
->decode_ibuf
);
257 * sst_wake_up_alloc_block - wake up waiting block
259 * @sst_drv_ctx: Driver context
261 * @status: status of wakeup
262 * @data: data pointer of wakeup
264 * This function wakes up a sleeping block event based on the response
266 void sst_wake_up_alloc_block(struct intel_sst_drv
*sst_drv_ctx
,
267 u8 sst_id
, int status
, void *data
)
271 /* Unblock with retval code */
272 for (i
= 0; i
< MAX_ACTIVE_STREAM
; i
++) {
273 if (sst_id
== sst_drv_ctx
->alloc_block
[i
].sst_id
) {
274 sst_drv_ctx
->alloc_block
[i
].ops_block
.condition
= true;
275 sst_drv_ctx
->alloc_block
[i
].ops_block
.ret_code
= status
;
276 sst_drv_ctx
->alloc_block
[i
].ops_block
.data
= data
;
277 wake_up(&sst_drv_ctx
->wait_queue
);
284 * sst_enable_rx_timeslot - Send msg to query for stream parameters
285 * @status: rx timeslot to be enabled
287 * This function is called when the RX timeslot is required to be enabled
289 int sst_enable_rx_timeslot(int status
)
292 struct ipc_post
*msg
= NULL
;
294 if (sst_create_short_msg(&msg
)) {
295 pr_err("mem allocation failed\n");
298 pr_debug("ipc message sending: ENABLE_RX_TIME_SLOT\n");
299 sst_fill_header(&msg
->header
, IPC_IA_ENABLE_RX_TIME_SLOT
, 0, 0);
300 msg
->header
.part
.data
= status
;
301 sst_drv_ctx
->hs_info_blk
.condition
= false;
302 sst_drv_ctx
->hs_info_blk
.ret_code
= 0;
303 sst_drv_ctx
->hs_info_blk
.on
= true;
304 spin_lock(&sst_drv_ctx
->list_spin_lock
);
305 list_add_tail(&msg
->node
,
306 &sst_drv_ctx
->ipc_dispatch_list
);
307 spin_unlock(&sst_drv_ctx
->list_spin_lock
);
308 sst_post_message(&sst_drv_ctx
->ipc_post_msg_wq
);
309 retval
= sst_wait_interruptible_timeout(sst_drv_ctx
,
310 &sst_drv_ctx
->hs_info_blk
, SST_BLOCK_TIMEOUT
);