Exemple #1
0
/**
* sst_get_fw_info - Send msg to query for firmware configurations
* @info: out param that holds the firmare configurations
*
* This function is called when the firmware configurations are queiried for
*/
int sst_get_fw_info(struct snd_sst_fw_info *info)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	unsigned long irq_flags;

	pr_debug("sst_get_fw_info called\n");

	if (sst_create_short_msg(&msg)) {
		pr_err("message creation failed\n");
		return -ENOMEM;
	}

	sst_fill_header(&msg->header, IPC_IA_GET_FW_INFO, 0, 0);
	sst_drv_ctx->fw_info_blk.condition = false;
	sst_drv_ctx->fw_info_blk.ret_code = 0;
	sst_drv_ctx->fw_info_blk.on = true;
	sst_drv_ctx->fw_info_blk.data = info;
	spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags);
	sst_drv_ctx->ops->post_message(&sst_drv_ctx->ipc_post_msg_wq);
	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->fw_info_blk);
	if (retval) {
		pr_err("error in fw_info = %d\n", retval);
		retval = -EIO;
	}
	return retval;
}
Exemple #2
0
/**
 * sst_resume_stream - Send msg for resuming stream
 * @str_id:		stream ID
 *
 * This function is called by any function which wants to resume
 * an already paused stream.
 */
int sst_resume_stream(int str_id)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct stream_info *str_info;
	struct intel_sst_ops *ops;
	unsigned long irq_flags;

	pr_debug("SST DBG:sst_resume_stream for %d\n", str_id);
	str_info = get_stream_info(str_id);
	if (!str_info)
		return -EINVAL;
	ops = sst_drv_ctx->ops;
	if (str_info->status == STREAM_RUNNING)
			return 0;
	if (str_info->status == STREAM_PAUSED) {
		if (str_info->ctrl_blk.on == true) {
			pr_err("SST ERR: control path in use\n");
			return -EINVAL;
		}
		if (sst_create_short_msg(&msg)) {
			pr_err("SST ERR: mem allocation failed\n");
			return -ENOMEM;
		}
		sst_fill_header(&msg->header, IPC_IA_RESUME_STREAM, 0, str_id);
		str_info->ctrl_blk.condition = false;
		str_info->ctrl_blk.ret_code = 0;
		str_info->ctrl_blk.on = true;
		spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		list_add_tail(&msg->node,
				&sst_drv_ctx->ipc_dispatch_list);
		spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		ops->post_message(&sst_drv_ctx->ipc_post_msg_wq);
		retval = sst_wait_timeout(sst_drv_ctx, &str_info->ctrl_blk);
		if (!retval) {
			if (str_info->prev == STREAM_RUNNING)
				str_info->status = STREAM_RUNNING;
			else
				str_info->status = STREAM_INIT;
			str_info->prev = STREAM_PAUSED;
		} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
			retval = -EINVAL;
			mutex_lock(&sst_drv_ctx->stream_lock);
			sst_clean_stream(str_info);
			mutex_unlock(&sst_drv_ctx->stream_lock);
		}
	} else {
		retval = -EBADRQC;
		pr_err("SST ERR: BADQRC for stream\n");
	}

	return retval;
}
Exemple #3
0
/*
 * sst_send_sound_card_type - send sound card type
 *
 * this function sends the sound card type to sst dsp engine
 */
static void sst_send_sound_card_type(void)
{
	struct ipc_post *msg = NULL;

	if (sst_create_short_msg(&msg))
		return;

	sst_fill_header(&msg->header, IPC_IA_SET_PMIC_TYPE, 0, 0);
	msg->header.part.data = sst_drv_ctx->pmic_vendor;
	spin_lock(&sst_drv_ctx->list_spin_lock);
	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;
}
Exemple #4
0
/**
* sst_drain_stream - Send msg for draining stream
* @str_id:		stream ID
*
* This function is called by any function which wants to drain
* a stream.
*/
int sst_drain_stream(int str_id)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct stream_info *str_info;
	struct intel_sst_ops *ops;
	unsigned long irq_flags;

	pr_debug("SST DBG:sst_drain_stream for %d\n", str_id);
	str_info = get_stream_info(str_id);
	if (!str_info)
		return -EINVAL;
	ops = sst_drv_ctx->ops;
	if (str_info->status != STREAM_RUNNING &&
		str_info->status != STREAM_INIT &&
		str_info->status != STREAM_PAUSED) {
			pr_err("SST ERR: BADQRC for stream = %d\n",
				       str_info->status);
			return -EBADRQC;
	}

	if (str_info->status == STREAM_INIT) {
		if (sst_create_short_msg(&msg)) {
			pr_err("SST ERR: mem allocation failed\n");
			return -ENOMEM;
		}
		sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, 0, str_id);
		spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
		spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		ops->post_message(&sst_drv_ctx->ipc_post_msg_wq);
		str_info->data_blk.condition = false;
		str_info->data_blk.ret_code = 0;
		str_info->data_blk.on = true;
		retval = sst_wait_interruptible(sst_drv_ctx,
						&str_info->data_blk);
	}
	return retval;
}
Exemple #5
0
/**
 * sst_free_stream - Frees a stream
 * @str_id:		stream ID
 *
 * This function is called by any function which wants to free
 * a stream.
 */
int sst_free_stream(int str_id)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct stream_info *str_info;
	struct intel_sst_ops *ops;
	unsigned long irq_flags;

	pr_debug("SST DBG:sst_free_stream for %d\n", str_id);

	mutex_lock(&sst_drv_ctx->sst_lock);
	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
		mutex_unlock(&sst_drv_ctx->sst_lock);
		return -ENODEV;
	}
	mutex_unlock(&sst_drv_ctx->sst_lock);
	str_info = get_stream_info(str_id);
	if (!str_info)
		return -EINVAL;
	ops = sst_drv_ctx->ops;

	mutex_lock(&str_info->lock);
	if (str_info->status != STREAM_UN_INIT) {
		str_info->prev =  str_info->status;
		str_info->status = STREAM_UN_INIT;
		mutex_unlock(&str_info->lock);
		if (str_info->ctrl_blk.on == true) {
			pr_err("SST ERR: control path in use\n");
			return -EINVAL;
		}
		if (sst_create_short_msg(&msg)) {
			pr_err("SST ERR: mem allocation failed\n");
			return -ENOMEM;
		}
		if (sst_drv_ctx->pci_id == SST_MRFLD_PCI_ID)
			sst_fill_header_mrfld(&msg->mrfld_header,
						IPC_IA_FREE_STREAM, 0, str_id);
		else
			sst_fill_header(&msg->header, IPC_IA_FREE_STREAM,
								 0, str_id);
		spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
		spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags);
		if (str_info->data_blk.on == true) {
			str_info->data_blk.condition = true;
			str_info->data_blk.ret_code = 0;
			wake_up(&sst_drv_ctx->wait_queue);
		}
		str_info->ctrl_blk.on = true;
		str_info->ctrl_blk.condition = false;
		ops->post_message(&sst_drv_ctx->ipc_post_msg_wq);
		retval = sst_wait_timeout(sst_drv_ctx, &str_info->ctrl_blk);
		pr_debug("sst: wait for free returned %d\n", retval);
		mutex_lock(&sst_drv_ctx->stream_lock);
		sst_clean_stream(str_info);
		mutex_unlock(&sst_drv_ctx->stream_lock);
		pr_debug("SST DBG:Stream freed\n");
	} else {
		mutex_unlock(&str_info->lock);
		retval = -EBADRQC;
		pr_debug("SST DBG:BADQRC for stream\n");
	}

	return retval;
}