struct snd_sst_mmap_buff_entry *tmp_buf;
pr_debug("called for str_id %d\n", str_id);
- stream = get_stream_info(str_id);
- if (!stream)
+ retval = sst_validate_strid(str_id);
+ if (retval)
return -EINVAL;
+ stream = &sst_drv_ctx->streams[str_id];
if (stream->mmapped != true)
return -EIO;
struct iovec iovec;
unsigned long nr_segs;
- stream = get_stream_info(str_id);
- if (!stream)
+ retval = sst_validate_strid(str_id);
+ if (retval)
return -EINVAL;
+ stream = &sst_drv_ctx->streams[str_id];
if (stream->mmapped == true) {
pr_warn("user write and stream is mapped\n");
return -EIO;
return -EINVAL;
pr_debug("called for str_id %d\n", str_id);
- stream = get_stream_info(str_id);
- if (!stream)
+ retval = sst_validate_strid(str_id);
+ if (retval)
return -EINVAL;
+ stream = &sst_drv_ctx->streams[str_id];
if (stream->mmapped == true)
return -EIO;
if (stream->status == STREAM_UN_INIT ||
}
pr_debug("called for str_id %d\n", str_id);
- stream = get_stream_info(str_id);
- if (!stream)
+ retval = sst_validate_strid(str_id);
+ if (retval)
return -EINVAL;
+ stream = &sst_drv_ctx->streams[str_id];
if (stream->mmapped == true)
return -EIO;
if (stream->status == STREAM_UN_INIT ||
retval = -EINVAL;
break;
}
- stream = get_stream_info(str_id);
- if (!stream) {
- retval = -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
break;
- }
+ stream = &sst_drv_ctx->streams[str_id];
mutex_lock(&stream->lock);
if (stream->status == STREAM_INIT &&
stream->need_draining != true) {
int sst_set_vol(struct snd_sst_vol *set_vol);
int sst_set_mute(struct snd_sst_mute *set_mute);
-int sst_sync_post_message(struct ipc_post *msg);
+
void sst_post_message(struct work_struct *work);
void sst_process_message(struct work_struct *work);
void sst_process_reply(struct work_struct *work);
sst_drv_ctx->sst_state = sst_state;
mutex_unlock(&sst_drv_ctx->sst_lock);
}
-static inline struct stream_info *get_stream_info(int str_id)
-{
- if (sst_validate_strid(str_id))
- return NULL;
- return &sst_drv_ctx->streams[str_id];
-}
+
int register_sst(struct device *);
int unregister_sst(struct device *);
#endif /* __INTEL_SST_COMMON_H__ */
void free_stream_context(unsigned int str_id)
{
struct stream_info *stream;
- stream = get_stream_info(str_id);
- if (stream) {
+
+ if (!sst_validate_strid(str_id)) {
/* str_id is valid, so stream is alloacted */
+ stream = &sst_drv_ctx->streams[str_id];
if (sst_free_stream(str_id))
sst_clean_stream(&sst_drv_ctx->streams[str_id]);
if (stream->ops == STREAM_OPS_PLAYBACK ||
struct stream_info *stream;
pr_debug("stream free called\n");
- stream = get_stream_info(str_id);
- if (!stream)
+ if (sst_validate_strid(str_id))
return -EINVAL;
+ stream = &sst_drv_ctx->streams[str_id];
free_stream_context(str_id);
stream->pcm_substream = NULL;
stream->status = STREAM_UN_INIT;
return 0;
}
-int sst_send_sync_msg(int ipc, int str_id)
-{
- struct ipc_post *msg = NULL;
-
- if (sst_create_short_msg(&msg))
- return -ENOMEM;
- sst_fill_header(&msg->header, ipc, 0, str_id);
- return sst_sync_post_message(msg);
-}
-
/*
* sst_device_control - Set Control params
*
switch (cmd) {
case SST_SND_PAUSE:
- case SST_SND_RESUME: {
+ case SST_SND_RESUME:
+ case SST_SND_DROP:
+ case SST_SND_START: {
struct mad_ops_wq *work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work)
return -ENOMEM;
queue_work(sst_drv_ctx->mad_wq, &work->wq);
break;
}
- case SST_SND_START: {
- struct stream_info *str_info;
- int ipc;
- str_id = *(int *)arg;
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
- ipc = IPC_IA_START_STREAM;
- str_info->prev = str_info->status;
- str_info->status = STREAM_RUNNING;
- retval = sst_send_sync_msg(ipc, str_id);
- break;
- }
- case SST_SND_DROP: {
- struct stream_info *str_info;
- int ipc;
- str_id = *(int *)arg;
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
- ipc = IPC_IA_DROP_STREAM;
- str_info->prev = STREAM_UN_INIT;
- str_info->status = STREAM_INIT;
- retval = sst_send_sync_msg(ipc, str_id);
- break;
- }
case SST_SND_STREAM_INIT: {
struct pcm_stream_info *str_info;
struct stream_info *stream;
pr_debug("stream init called\n");
str_info = (struct pcm_stream_info *)arg;
str_id = str_info->str_id;
- stream = get_stream_info(str_id);
- if (!stream) {
- retval = -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
break;
- }
+
+ stream = &sst_drv_ctx->streams[str_id];
pr_debug("setting the period ptrs\n");
stream->pcm_substream = str_info->mad_substream;
stream->period_elapsed = str_info->period_elapsed;
stream_info = (struct pcm_stream_info *)arg;
str_id = stream_info->str_id;
- stream = get_stream_info(str_id);
- if (!stream) {
- retval = -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
break;
- }
+ stream = &sst_drv_ctx->streams[str_id];
if (!stream->pcm_substream)
break;
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/sched.h>
-#include <linux/delay.h>
#include <sound/intel_sst_ioctl.h>
#include "../sst_platform.h"
#include "intel_sst_fw_ipc.h"
kfree(msg);
}
-/* use this for trigger ops to post syncronous msgs
- */
-int sst_sync_post_message(struct ipc_post *msg)
-{
- union ipc_header header;
- unsigned int loop_count = 0;
- int retval = 0;
-
- pr_debug("sst: sync post message called\n");
- spin_lock(&sst_drv_ctx->list_spin_lock);
-
- /* check busy bit */
- header.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCX);
- while (header.part.busy) {
- if (loop_count > 10) {
- pr_err("busy wait failed, cant send this msg\n");
- retval = -EBUSY;
- goto out;
- }
- udelay(500);
- loop_count++;
- header.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCX);
- };
- pr_debug("sst: Post message: header = %x\n", msg->header.full);
- pr_debug("sst: size: = %x\n", msg->header.part.data);
- if (msg->header.part.large)
- memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND,
- msg->mailbox_data, msg->header.part.data);
-
- sst_shim_write(sst_drv_ctx->shim, SST_IPCX, msg->header.full);
-
-out:
- spin_unlock(&sst_drv_ctx->list_spin_lock);
- kfree(msg->mailbox_data);
- kfree(msg);
- return retval;
-}
-
/*
* sst_clear_interrupt - clear the SST FW interrupt
*
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
struct stream_info *stream ;
- stream = get_stream_info(str_id);
- if (!stream) {
+ if (sst_validate_strid(str_id)) {
pr_err("strid %d invalid\n", str_id);
break;
}
/* call sst_play_frame */
+ stream = &sst_drv_ctx->streams[str_id];
pr_debug("sst_play_frames for %d\n",
msg->header.part.str_id);
mutex_lock(&sst_drv_ctx->streams[str_id].lock);
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
struct stream_info *stream;
/* call sst_capture_frame */
- stream = get_stream_info(str_id);
- if (!stream) {
+ if (sst_validate_strid(str_id)) {
pr_err("str id %d invalid\n", str_id);
break;
}
+ stream = &sst_drv_ctx->streams[str_id];
pr_debug("sst_capture_frames for %d\n",
msg->header.part.str_id);
mutex_lock(&stream->lock);
break;
case IPC_IA_GET_STREAM_PARAMS:
- str_info = get_stream_info(str_id);
- if (!str_info) {
+ if (sst_validate_strid(str_id)) {
pr_err("stream id %d invalid\n", str_id);
break;
}
+ str_info = &sst_drv_ctx->streams[str_id];
if (msg->header.part.large) {
pr_debug("Get stream large success\n");
memcpy_fromio(str_info->ctrl_blk.data,
}
break;
case IPC_IA_DECODE_FRAMES:
- str_info = get_stream_info(str_id);
- if (!str_info) {
+ if (sst_validate_strid(str_id)) {
pr_err("stream id %d invalid\n", str_id);
break;
}
+ str_info = &sst_drv_ctx->streams[str_id];
if (msg->header.part.large) {
pr_debug("Msg succeeded %x\n",
msg->header.part.msg_id);
}
break;
case IPC_IA_DRAIN_STREAM:
- str_info = get_stream_info(str_id);
- if (!str_info) {
+ if (sst_validate_strid(str_id)) {
pr_err("stream id %d invalid\n", str_id);
break;
}
+ str_info = &sst_drv_ctx->streams[str_id];
if (!msg->header.part.data) {
pr_debug("Msg succeeded %x\n",
msg->header.part.msg_id);
break;
case IPC_IA_DROP_STREAM:
- str_info = get_stream_info(str_id);
- if (!str_info) {
+ if (sst_validate_strid(str_id)) {
pr_err("str id %d invalid\n", str_id);
break;
}
+ str_info = &sst_drv_ctx->streams[str_id];
if (msg->header.part.large) {
struct snd_sst_drop_response *drop_resp =
(struct snd_sst_drop_response *)msg->mailbox;
case IPC_IA_PAUSE_STREAM:
case IPC_IA_RESUME_STREAM:
case IPC_IA_SET_STREAM_PARAMS:
- str_info = get_stream_info(str_id);
- if (!str_info) {
- pr_err(" stream id %d invalid\n", str_id);
- break;
- }
+ str_info = &sst_drv_ctx->streams[str_id];
if (!msg->header.part.data) {
pr_debug("Msg succeeded %x\n",
msg->header.part.msg_id);
msg->header.part.data);
str_info->ctrl_blk.ret_code = -msg->header.part.data;
}
+ if (sst_validate_strid(str_id)) {
+ pr_err(" stream id %d invalid\n", str_id);
+ break;
+ }
if (str_info->ctrl_blk.on == true) {
str_info->ctrl_blk.on = false;
*/
int sst_start_stream(int str_id)
{
+ int retval = 0;
struct ipc_post *msg = NULL;
struct stream_info *str_info;
pr_debug("sst_start_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status != STREAM_INIT)
return -EBADRQC;
if (sst_create_short_msg(&msg))
list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
spin_unlock(&sst_drv_ctx->list_spin_lock);
sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
- return 0;
+ return retval;
}
/*
struct stream_info *str_info;
pr_debug("SST DBG:sst_pause_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status == STREAM_PAUSED)
return 0;
if (str_info->status == STREAM_RUNNING ||
struct stream_info *str_info;
pr_debug("SST DBG:sst_resume_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status == STREAM_RUNNING)
return 0;
if (str_info->status == STREAM_PAUSED) {
struct stream_info *str_info;
pr_debug("SST DBG:sst_drop_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
mutex_lock(&str_info->lock);
if (str_info->status != STREAM_UN_INIT &&
struct stream_info *str_info;
pr_debug("SST DBG:sst_drain_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status != STREAM_RUNNING &&
str_info->status != STREAM_INIT &&
struct stream_info *str_info;
pr_debug("SST DBG:sst_free_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
mutex_lock(&str_info->lock);
if (str_info->status != STREAM_UN_INIT) {
struct snd_sst_fw_get_stream_params *fw_params;
pr_debug("get_stream for %d\n", str_id);
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status != STREAM_UN_INIT) {
if (str_info->ctrl_blk.on == true) {
pr_err("control path in use\n");
pr_err("Invalid operation\n");
return -EINVAL;
}
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
pr_debug("set_stream for %d\n", str_id);
+ str_info = &sst_drv_ctx->streams[str_id];
if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
if (str_info->ctrl_blk.on == true) {
pr_err("control path in use\n");
*/
int sst_play_frame(int str_id)
{
+ int retval = 0;
struct ipc_post *msg = NULL;
struct sst_frame_info sg_list = {0};
struct sst_stream_bufs *kbufs = NULL, *_kbufs;
struct stream_info *stream;
pr_debug("play frame for %d\n", str_id);
- stream = get_stream_info(str_id);
- if (!stream)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ stream = &sst_drv_ctx->streams[str_id];
/* clear prev sent buffers */
list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
if (kbufs->in_use == true) {
*/
int sst_capture_frame(int str_id)
{
+ int retval = 0;
struct ipc_post *msg = NULL;
struct sst_frame_info sg_list = {0};
struct sst_stream_bufs *kbufs = NULL, *_kbufs;
pr_debug("capture frame for %d\n", str_id);
- stream = get_stream_info(str_id);
- if (!stream)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ stream = &sst_drv_ctx->streams[str_id];
/* clear prev sent buffers */
list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
if (kbufs->in_use == true) {
pr_debug("Powering_down_PMIC...\n");
- str_info = get_stream_info(str_id);
- if (!str_info)
- return -EINVAL;
+ retval = sst_validate_strid(str_id);
+ if (retval)
+ return retval;
+ str_info = &sst_drv_ctx->streams[str_id];
if (str_info->status != STREAM_INIT) {
pr_err("invalid stream state = %d\n",
str_info->status);